From 1ef6b24d1359da855fbc2eff6f9b7dbbabd5cb1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 28 Apr 2023 12:02:13 +0200 Subject: [PATCH] Avoid subtype reduction when creating a union result in `discriminateTypeByDiscriminableItems` --- src/compiler/checker.ts | 2 +- .../contextualTypeSelfReferencing.symbols | 40 +++++++++++++++++++ .../contextualTypeSelfReferencing.types | 26 ++++++++++++ .../compiler/contextualTypeSelfReferencing.ts | 16 ++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/contextualTypeSelfReferencing.symbols create mode 100644 tests/baselines/reference/contextualTypeSelfReferencing.types create mode 100644 tests/cases/compiler/contextualTypeSelfReferencing.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1266af4184020..e474ef533bff8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22684,7 +22684,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } - const filtered = contains(include, Ternary.False) ? getUnionType(types.filter((_, i) => include[i])) : target; + const filtered = contains(include, Ternary.False) ? getUnionType(types.filter((_, i) => include[i]), UnionReduction.None) : target; return filtered.flags & TypeFlags.Never ? target : filtered; } diff --git a/tests/baselines/reference/contextualTypeSelfReferencing.symbols b/tests/baselines/reference/contextualTypeSelfReferencing.symbols new file mode 100644 index 0000000000000..3841325def3a2 --- /dev/null +++ b/tests/baselines/reference/contextualTypeSelfReferencing.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/contextualTypeSelfReferencing.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54048 + +type narrow = def extends string +>narrow : Symbol(narrow, Decl(contextualTypeSelfReferencing.ts, 0, 0)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) + + ? def +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) + + : def extends [unknown, ...unknown[]] +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) + + ? def +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) + + : { + [k in keyof def]: narrow; +>k : Symbol(k, Decl(contextualTypeSelfReferencing.ts, 7, 7)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) +>narrow : Symbol(narrow, Decl(contextualTypeSelfReferencing.ts, 0, 0)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 2, 12)) +>k : Symbol(k, Decl(contextualTypeSelfReferencing.ts, 7, 7)) + + }; + +declare const parse: (def: narrow) => def; +>parse : Symbol(parse, Decl(contextualTypeSelfReferencing.ts, 10, 13)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 10, 22), Decl(contextualTypeSelfReferencing.ts, 10, 27)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 10, 22), Decl(contextualTypeSelfReferencing.ts, 10, 27)) +>narrow : Symbol(narrow, Decl(contextualTypeSelfReferencing.ts, 0, 0)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 10, 22), Decl(contextualTypeSelfReferencing.ts, 10, 27)) +>def : Symbol(def, Decl(contextualTypeSelfReferencing.ts, 10, 22), Decl(contextualTypeSelfReferencing.ts, 10, 27)) + +const result = parse([{ a: "foo" }]); +>result : Symbol(result, Decl(contextualTypeSelfReferencing.ts, 12, 5)) +>parse : Symbol(parse, Decl(contextualTypeSelfReferencing.ts, 10, 13)) +>a : Symbol(a, Decl(contextualTypeSelfReferencing.ts, 12, 23)) + diff --git a/tests/baselines/reference/contextualTypeSelfReferencing.types b/tests/baselines/reference/contextualTypeSelfReferencing.types new file mode 100644 index 0000000000000..2c67613e1e7ca --- /dev/null +++ b/tests/baselines/reference/contextualTypeSelfReferencing.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/contextualTypeSelfReferencing.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54048 + +type narrow = def extends string +>narrow : narrow + + ? def + : def extends [unknown, ...unknown[]] + ? def + : { + [k in keyof def]: narrow; + }; + +declare const parse: (def: narrow) => def; +>parse : (def: narrow) => def +>def : narrow + +const result = parse([{ a: "foo" }]); +>result : [{ a: "foo"; }] +>parse([{ a: "foo" }]) : [{ a: "foo"; }] +>parse : (def: narrow) => def +>[{ a: "foo" }] : [{ a: "foo"; }] +>{ a: "foo" } : { a: "foo"; } +>a : "foo" +>"foo" : "foo" + diff --git a/tests/cases/compiler/contextualTypeSelfReferencing.ts b/tests/cases/compiler/contextualTypeSelfReferencing.ts new file mode 100644 index 0000000000000..f20d5aa1eb26b --- /dev/null +++ b/tests/cases/compiler/contextualTypeSelfReferencing.ts @@ -0,0 +1,16 @@ +// @strict: true +// @noEmit: true + +// repro from https://github.com/microsoft/TypeScript/issues/54048 + +type narrow = def extends string + ? def + : def extends [unknown, ...unknown[]] + ? def + : { + [k in keyof def]: narrow; + }; + +declare const parse: (def: narrow) => def; + +const result = parse([{ a: "foo" }]); \ No newline at end of file