From 942d2a91c115f22857513a9d3f4bde2fb1521f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 24 May 2022 10:05:39 +0200 Subject: [PATCH 1/2] Fixed an issue with conditional types not being able to infer from nested tuple types of the same shape --- src/compiler/checker.ts | 3 +-- ...onalTypeInferFromNestedSameShapeTuple.symbols | 16 ++++++++++++++++ ...tionalTypeInferFromNestedSameShapeTuple.types | 9 +++++++++ ...nditionalTypeInferFromNestedSameShapeTuple.ts | 7 +++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols create mode 100644 tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types create mode 100644 tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bcc6f5bdc65a..44fb6d48bf404 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20929,8 +20929,7 @@ namespace ts { return type.symbol; } if (isTupleType(type)) { - // Tuple types are tracked through their target type - return type.target; + return type; } } if (type.flags & TypeFlags.TypeParameter) { diff --git a/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols b/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols new file mode 100644 index 0000000000000..0d7ffbaacd120 --- /dev/null +++ b/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts === +// repro #48524 + +type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; +>Magic : Symbol(Magic, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 0, 0)) +>X : Symbol(X, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 11)) +>X : Symbol(X, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 11)) +>Y : Symbol(Y, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 33)) +>_ : Symbol(_, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 45)) +>__ : Symbol(__, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 58)) +>Y : Symbol(Y, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 33)) + +type R = Magic<[[number]]> +>R : Symbol(R, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 75)) +>Magic : Symbol(Magic, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 0, 0)) + diff --git a/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types b/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types new file mode 100644 index 0000000000000..0bc7c8bc5304e --- /dev/null +++ b/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts === +// repro #48524 + +type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; +>Magic : Magic + +type R = Magic<[[number]]> +>R : number + diff --git a/tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts b/tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts new file mode 100644 index 0000000000000..263ac9124b6b1 --- /dev/null +++ b/tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts @@ -0,0 +1,7 @@ +// @noEmit: true + +// repro #48524 + +type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; + +type R = Magic<[[number]]> From a7d58263b3dea12ad4f976fe32ff3251b0e2867b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 23 Feb 2023 11:35:42 +0100 Subject: [PATCH 2/2] Add extra test cases --- ...lTypeInferFromNestedSameShapeTuple.symbols | 16 ---- ...nalTypeInferFromNestedSameShapeTuple.types | 9 -- .../inferFromNestedSameShapeTuple.symbols | 86 +++++++++++++++++++ .../inferFromNestedSameShapeTuple.types | 86 +++++++++++++++++++ ...tionalTypeInferFromNestedSameShapeTuple.ts | 7 -- .../compiler/inferFromNestedSameShapeTuple.ts | 36 ++++++++ 6 files changed, 208 insertions(+), 32 deletions(-) delete mode 100644 tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols delete mode 100644 tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types create mode 100644 tests/baselines/reference/inferFromNestedSameShapeTuple.symbols create mode 100644 tests/baselines/reference/inferFromNestedSameShapeTuple.types delete mode 100644 tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts create mode 100644 tests/cases/compiler/inferFromNestedSameShapeTuple.ts diff --git a/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols b/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols deleted file mode 100644 index 0d7ffbaacd120..0000000000000 --- a/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.symbols +++ /dev/null @@ -1,16 +0,0 @@ -=== tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts === -// repro #48524 - -type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; ->Magic : Symbol(Magic, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 0, 0)) ->X : Symbol(X, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 11)) ->X : Symbol(X, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 11)) ->Y : Symbol(Y, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 33)) ->_ : Symbol(_, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 45)) ->__ : Symbol(__, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 58)) ->Y : Symbol(Y, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 33)) - -type R = Magic<[[number]]> ->R : Symbol(R, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 2, 75)) ->Magic : Symbol(Magic, Decl(conditionalTypeInferFromNestedSameShapeTuple.ts, 0, 0)) - diff --git a/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types b/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types deleted file mode 100644 index 0bc7c8bc5304e..0000000000000 --- a/tests/baselines/reference/conditionalTypeInferFromNestedSameShapeTuple.types +++ /dev/null @@ -1,9 +0,0 @@ -=== tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts === -// repro #48524 - -type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; ->Magic : Magic - -type R = Magic<[[number]]> ->R : number - diff --git a/tests/baselines/reference/inferFromNestedSameShapeTuple.symbols b/tests/baselines/reference/inferFromNestedSameShapeTuple.symbols new file mode 100644 index 0000000000000..789febc6172e0 --- /dev/null +++ b/tests/baselines/reference/inferFromNestedSameShapeTuple.symbols @@ -0,0 +1,86 @@ +=== tests/cases/compiler/inferFromNestedSameShapeTuple.ts === +// repro #48524 + +type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; +>Magic : Symbol(Magic, Decl(inferFromNestedSameShapeTuple.ts, 0, 0)) +>X : Symbol(X, Decl(inferFromNestedSameShapeTuple.ts, 2, 11)) +>X : Symbol(X, Decl(inferFromNestedSameShapeTuple.ts, 2, 11)) +>Y : Symbol(Y, Decl(inferFromNestedSameShapeTuple.ts, 2, 33)) +>_ : Symbol(_, Decl(inferFromNestedSameShapeTuple.ts, 2, 45)) +>__ : Symbol(__, Decl(inferFromNestedSameShapeTuple.ts, 2, 58)) +>Y : Symbol(Y, Decl(inferFromNestedSameShapeTuple.ts, 2, 33)) + +type R = Magic<[[number]]> +>R : Symbol(R, Decl(inferFromNestedSameShapeTuple.ts, 2, 75)) +>Magic : Symbol(Magic, Decl(inferFromNestedSameShapeTuple.ts, 0, 0)) + +// repro #52722 + +type Recursive = { +>Recursive : Symbol(Recursive, Decl(inferFromNestedSameShapeTuple.ts, 4, 26)) +>Id : Symbol(Id, Decl(inferFromNestedSameShapeTuple.ts, 8, 15)) + + id: Id +>id : Symbol(id, Decl(inferFromNestedSameShapeTuple.ts, 8, 22)) +>Id : Symbol(Id, Decl(inferFromNestedSameShapeTuple.ts, 8, 15)) + + children: readonly Recursive[] +>children : Symbol(children, Decl(inferFromNestedSameShapeTuple.ts, 9, 10)) +>Recursive : Symbol(Recursive, Decl(inferFromNestedSameShapeTuple.ts, 4, 26)) +>Id : Symbol(Id, Decl(inferFromNestedSameShapeTuple.ts, 8, 15)) +} + +declare function getIds(items: readonly Recursive[]): Id[]; +>getIds : Symbol(getIds, Decl(inferFromNestedSameShapeTuple.ts, 11, 1)) +>Id : Symbol(Id, Decl(inferFromNestedSameShapeTuple.ts, 13, 24)) +>items : Symbol(items, Decl(inferFromNestedSameShapeTuple.ts, 13, 28)) +>Recursive : Symbol(Recursive, Decl(inferFromNestedSameShapeTuple.ts, 4, 26)) +>Id : Symbol(Id, Decl(inferFromNestedSameShapeTuple.ts, 13, 24)) +>Id : Symbol(Id, Decl(inferFromNestedSameShapeTuple.ts, 13, 24)) + +const items = [{ +>items : Symbol(items, Decl(inferFromNestedSameShapeTuple.ts, 15, 5)) + + id: 'a', +>id : Symbol(id, Decl(inferFromNestedSameShapeTuple.ts, 15, 16)) + + children: [{ +>children : Symbol(children, Decl(inferFromNestedSameShapeTuple.ts, 16, 12)) + + id: 'b', +>id : Symbol(id, Decl(inferFromNestedSameShapeTuple.ts, 17, 16)) + + children: [] +>children : Symbol(children, Decl(inferFromNestedSameShapeTuple.ts, 18, 16)) + + }] +}] as const satisfies readonly Recursive[] +>const : Symbol(const) +>Recursive : Symbol(Recursive, Decl(inferFromNestedSameShapeTuple.ts, 4, 26)) + +const foo = getIds(items) +>foo : Symbol(foo, Decl(inferFromNestedSameShapeTuple.ts, 23, 5)) +>getIds : Symbol(getIds, Decl(inferFromNestedSameShapeTuple.ts, 11, 1)) +>items : Symbol(items, Decl(inferFromNestedSameShapeTuple.ts, 15, 5)) + +// variant with a fresh argument +const foo2 = getIds([{ +>foo2 : Symbol(foo2, Decl(inferFromNestedSameShapeTuple.ts, 26, 5)) +>getIds : Symbol(getIds, Decl(inferFromNestedSameShapeTuple.ts, 11, 1)) + + id: 'a', +>id : Symbol(id, Decl(inferFromNestedSameShapeTuple.ts, 26, 22)) + + children: [{ +>children : Symbol(children, Decl(inferFromNestedSameShapeTuple.ts, 27, 12)) + + id: 'b', +>id : Symbol(id, Decl(inferFromNestedSameShapeTuple.ts, 28, 16)) + + children: [] +>children : Symbol(children, Decl(inferFromNestedSameShapeTuple.ts, 29, 16)) + + }] +}] as const) +>const : Symbol(const) + diff --git a/tests/baselines/reference/inferFromNestedSameShapeTuple.types b/tests/baselines/reference/inferFromNestedSameShapeTuple.types new file mode 100644 index 0000000000000..244d5f183906e --- /dev/null +++ b/tests/baselines/reference/inferFromNestedSameShapeTuple.types @@ -0,0 +1,86 @@ +=== tests/cases/compiler/inferFromNestedSameShapeTuple.ts === +// repro #48524 + +type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; +>Magic : Magic + +type R = Magic<[[number]]> +>R : number + +// repro #52722 + +type Recursive = { +>Recursive : Recursive + + id: Id +>id : Id + + children: readonly Recursive[] +>children : readonly Recursive[] +} + +declare function getIds(items: readonly Recursive[]): Id[]; +>getIds : (items: readonly Recursive[]) => Id[] +>items : readonly Recursive[] + +const items = [{ +>items : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] +>[{ id: 'a', children: [{ id: 'b', children: [] }]}] as const satisfies readonly Recursive[] : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] +>[{ id: 'a', children: [{ id: 'b', children: [] }]}] as const : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] +>[{ id: 'a', children: [{ id: 'b', children: [] }]}] : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] +>{ id: 'a', children: [{ id: 'b', children: [] }]} : { readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; } + + id: 'a', +>id : "a" +>'a' : "a" + + children: [{ +>children : readonly [{ readonly id: "b"; readonly children: readonly []; }] +>[{ id: 'b', children: [] }] : readonly [{ readonly id: "b"; readonly children: readonly []; }] +>{ id: 'b', children: [] } : { readonly id: "b"; readonly children: readonly []; } + + id: 'b', +>id : "b" +>'b' : "b" + + children: [] +>children : readonly [] +>[] : readonly [] + + }] +}] as const satisfies readonly Recursive[] + +const foo = getIds(items) +>foo : ("a" | "b")[] +>getIds(items) : ("a" | "b")[] +>getIds : (items: readonly Recursive[]) => Id[] +>items : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] + +// variant with a fresh argument +const foo2 = getIds([{ +>foo2 : ("a" | "b")[] +>getIds([{ id: 'a', children: [{ id: 'b', children: [] }]}] as const) : ("a" | "b")[] +>getIds : (items: readonly Recursive[]) => Id[] +>[{ id: 'a', children: [{ id: 'b', children: [] }]}] as const : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] +>[{ id: 'a', children: [{ id: 'b', children: [] }]}] : readonly [{ readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; }] +>{ id: 'a', children: [{ id: 'b', children: [] }]} : { readonly id: "a"; readonly children: readonly [{ readonly id: "b"; readonly children: readonly []; }]; } + + id: 'a', +>id : "a" +>'a' : "a" + + children: [{ +>children : readonly [{ readonly id: "b"; readonly children: readonly []; }] +>[{ id: 'b', children: [] }] : readonly [{ readonly id: "b"; readonly children: readonly []; }] +>{ id: 'b', children: [] } : { readonly id: "b"; readonly children: readonly []; } + + id: 'b', +>id : "b" +>'b' : "b" + + children: [] +>children : readonly [] +>[] : readonly [] + + }] +}] as const) diff --git a/tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts b/tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts deleted file mode 100644 index 263ac9124b6b1..0000000000000 --- a/tests/cases/compiler/conditionalTypeInferFromNestedSameShapeTuple.ts +++ /dev/null @@ -1,7 +0,0 @@ -// @noEmit: true - -// repro #48524 - -type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; - -type R = Magic<[[number]]> diff --git a/tests/cases/compiler/inferFromNestedSameShapeTuple.ts b/tests/cases/compiler/inferFromNestedSameShapeTuple.ts new file mode 100644 index 0000000000000..60c83e484c4a1 --- /dev/null +++ b/tests/cases/compiler/inferFromNestedSameShapeTuple.ts @@ -0,0 +1,36 @@ +// @strict: true +// @noEmit: true + +// repro #48524 + +type Magic = X extends [[infer Y, ...infer _], ...infer __] ? Y : never; + +type R = Magic<[[number]]> + +// repro #52722 + +type Recursive = { + id: Id + children: readonly Recursive[] +} + +declare function getIds(items: readonly Recursive[]): Id[]; + +const items = [{ + id: 'a', + children: [{ + id: 'b', + children: [] + }] +}] as const satisfies readonly Recursive[] + +const foo = getIds(items) + +// variant with a fresh argument +const foo2 = getIds([{ + id: 'a', + children: [{ + id: 'b', + children: [] + }] +}] as const) \ No newline at end of file