From 0db3f9ecf3721a7fa34e73a649011ec4761aaf26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 1 Jan 2023 23:51:29 +0100 Subject: [PATCH] Add a test for indexed access on generic mapped type --- tests/baselines/reference/correlatedUnions.js | 62 +++++++++- .../reference/correlatedUnions.symbols | 106 +++++++++++++++++- .../reference/correlatedUnions.types | 77 ++++++++++++- tests/cases/compiler/correlatedUnions.ts | 37 +++++- 4 files changed, 276 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/correlatedUnions.js b/tests/baselines/reference/correlatedUnions.js index 03de1a814ba75..dbcc6db949cde 100644 --- a/tests/baselines/reference/correlatedUnions.js +++ b/tests/baselines/reference/correlatedUnions.js @@ -174,7 +174,7 @@ function f2(funcs: Funcs, key: K, arg: ArgMap[K]) { } function f3(funcs: Funcs, key: K, arg: ArgMap[K]) { - const func: Func = funcs[key]; // Error, Funcs[K] not assignable to Func + const func: Func = funcs[key]; func(arg); } @@ -234,7 +234,41 @@ const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name'); type BarLookup = typeof BAR_LOOKUP; type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] }; - + +// repro from #43982 + +interface Original { + prop1: { + subProp1: string; + subProp2: string; + }; + prop2: { + subProp3: string; + subProp4: string; + }; +} +type KeyOfOriginal = keyof Original; +type NestedKeyOfOriginalFor = keyof Original[T]; + +type SameKeys = { + [K in keyof T]: { + [K2 in keyof T[K]]: number; + }; +}; + +type MappedFromOriginal = SameKeys; + +const getStringAndNumberFromOriginalAndMapped = < + K extends KeyOfOriginal, + N extends NestedKeyOfOriginalFor +>( + original: Original, + mappedFromOriginal: MappedFromOriginal, + key: K, + nestedKey: N +): [Original[K][N], MappedFromOriginal[K][N]] => { + return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]]; +}; //// [correlatedUnions.js] "use strict"; @@ -329,7 +363,7 @@ function f2(funcs, key, arg) { func(arg); } function f3(funcs, key, arg) { - var func = funcs[key]; // Error, Funcs[K] not assignable to Func + var func = funcs[key]; func(arg); } function f4(x, y) { @@ -355,6 +389,9 @@ function foo(prop, f) { } var ALL_BARS = [{ name: 'a' }, { name: 'b' }]; var BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name'); +var getStringAndNumberFromOriginalAndMapped = function (original, mappedFromOriginal, key, nestedKey) { + return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]]; +}; //// [correlatedUnions.d.ts] @@ -506,3 +543,22 @@ type BarLookup = typeof BAR_LOOKUP; type Baz = { [K in keyof BarLookup]: BarLookup[K]['name']; }; +interface Original { + prop1: { + subProp1: string; + subProp2: string; + }; + prop2: { + subProp3: string; + subProp4: string; + }; +} +type KeyOfOriginal = keyof Original; +type NestedKeyOfOriginalFor = keyof Original[T]; +type SameKeys = { + [K in keyof T]: { + [K2 in keyof T[K]]: number; + }; +}; +type MappedFromOriginal = SameKeys; +declare const getStringAndNumberFromOriginalAndMapped: (original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N) => [Original[K][N], SameKeys[K][N]]; diff --git a/tests/baselines/reference/correlatedUnions.symbols b/tests/baselines/reference/correlatedUnions.symbols index 9485b70c5dcd5..c1948aef3eef6 100644 --- a/tests/baselines/reference/correlatedUnions.symbols +++ b/tests/baselines/reference/correlatedUnions.symbols @@ -647,7 +647,7 @@ function f3(funcs: Funcs, key: K, arg: ArgMap[K]) { >ArgMap : Symbol(ArgMap, Decl(correlatedUnions.ts, 157, 1)) >K : Symbol(K, Decl(correlatedUnions.ts, 174, 12)) - const func: Func = funcs[key]; // Error, Funcs[K] not assignable to Func + const func: Func = funcs[key]; >func : Symbol(func, Decl(correlatedUnions.ts, 175, 9)) >Func : Symbol(Func, Decl(correlatedUnions.ts, 161, 39)) >K : Symbol(K, Decl(correlatedUnions.ts, 174, 12)) @@ -824,3 +824,107 @@ type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] }; >BarLookup : Symbol(BarLookup, Decl(correlatedUnions.ts, 230, 63)) >K : Symbol(K, Decl(correlatedUnions.ts, 234, 14)) +// repro from #43982 + +interface Original { +>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60)) + + prop1: { +>prop1 : Symbol(Original.prop1, Decl(correlatedUnions.ts, 238, 20)) + + subProp1: string; +>subProp1 : Symbol(subProp1, Decl(correlatedUnions.ts, 239, 10)) + + subProp2: string; +>subProp2 : Symbol(subProp2, Decl(correlatedUnions.ts, 240, 21)) + + }; + prop2: { +>prop2 : Symbol(Original.prop2, Decl(correlatedUnions.ts, 242, 4)) + + subProp3: string; +>subProp3 : Symbol(subProp3, Decl(correlatedUnions.ts, 243, 10)) + + subProp4: string; +>subProp4 : Symbol(subProp4, Decl(correlatedUnions.ts, 244, 21)) + + }; +} +type KeyOfOriginal = keyof Original; +>KeyOfOriginal : Symbol(KeyOfOriginal, Decl(correlatedUnions.ts, 247, 1)) +>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60)) + +type NestedKeyOfOriginalFor = keyof Original[T]; +>NestedKeyOfOriginalFor : Symbol(NestedKeyOfOriginalFor, Decl(correlatedUnions.ts, 248, 36)) +>T : Symbol(T, Decl(correlatedUnions.ts, 249, 28)) +>KeyOfOriginal : Symbol(KeyOfOriginal, Decl(correlatedUnions.ts, 247, 1)) +>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60)) +>T : Symbol(T, Decl(correlatedUnions.ts, 249, 28)) + +type SameKeys = { +>SameKeys : Symbol(SameKeys, Decl(correlatedUnions.ts, 249, 73)) +>T : Symbol(T, Decl(correlatedUnions.ts, 251, 14)) + + [K in keyof T]: { +>K : Symbol(K, Decl(correlatedUnions.ts, 252, 3)) +>T : Symbol(T, Decl(correlatedUnions.ts, 251, 14)) + + [K2 in keyof T[K]]: number; +>K2 : Symbol(K2, Decl(correlatedUnions.ts, 253, 5)) +>T : Symbol(T, Decl(correlatedUnions.ts, 251, 14)) +>K : Symbol(K, Decl(correlatedUnions.ts, 252, 3)) + + }; +}; + +type MappedFromOriginal = SameKeys; +>MappedFromOriginal : Symbol(MappedFromOriginal, Decl(correlatedUnions.ts, 255, 2)) +>SameKeys : Symbol(SameKeys, Decl(correlatedUnions.ts, 249, 73)) +>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60)) + +const getStringAndNumberFromOriginalAndMapped = < +>getStringAndNumberFromOriginalAndMapped : Symbol(getStringAndNumberFromOriginalAndMapped, Decl(correlatedUnions.ts, 259, 5)) + + K extends KeyOfOriginal, +>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49)) +>KeyOfOriginal : Symbol(KeyOfOriginal, Decl(correlatedUnions.ts, 247, 1)) + + N extends NestedKeyOfOriginalFor +>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26)) +>NestedKeyOfOriginalFor : Symbol(NestedKeyOfOriginalFor, Decl(correlatedUnions.ts, 248, 36)) +>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49)) + +>( + original: Original, +>original : Symbol(original, Decl(correlatedUnions.ts, 262, 2)) +>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60)) + + mappedFromOriginal: MappedFromOriginal, +>mappedFromOriginal : Symbol(mappedFromOriginal, Decl(correlatedUnions.ts, 263, 21)) +>MappedFromOriginal : Symbol(MappedFromOriginal, Decl(correlatedUnions.ts, 255, 2)) + + key: K, +>key : Symbol(key, Decl(correlatedUnions.ts, 264, 41)) +>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49)) + + nestedKey: N +>nestedKey : Symbol(nestedKey, Decl(correlatedUnions.ts, 265, 9)) +>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26)) + +): [Original[K][N], MappedFromOriginal[K][N]] => { +>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60)) +>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49)) +>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26)) +>MappedFromOriginal : Symbol(MappedFromOriginal, Decl(correlatedUnions.ts, 255, 2)) +>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49)) +>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26)) + + return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]]; +>original : Symbol(original, Decl(correlatedUnions.ts, 262, 2)) +>key : Symbol(key, Decl(correlatedUnions.ts, 264, 41)) +>nestedKey : Symbol(nestedKey, Decl(correlatedUnions.ts, 265, 9)) +>mappedFromOriginal : Symbol(mappedFromOriginal, Decl(correlatedUnions.ts, 263, 21)) +>key : Symbol(key, Decl(correlatedUnions.ts, 264, 41)) +>nestedKey : Symbol(nestedKey, Decl(correlatedUnions.ts, 265, 9)) + +}; diff --git a/tests/baselines/reference/correlatedUnions.types b/tests/baselines/reference/correlatedUnions.types index 6d2074195b17c..496dbc91eb4a9 100644 --- a/tests/baselines/reference/correlatedUnions.types +++ b/tests/baselines/reference/correlatedUnions.types @@ -601,7 +601,7 @@ function f3(funcs: Funcs, key: K, arg: ArgMap[K]) { >key : K >arg : ArgMap[K] - const func: Func = funcs[key]; // Error, Funcs[K] not assignable to Func + const func: Func = funcs[key]; >func : Func >funcs[key] : Funcs[K] >funcs : Funcs @@ -753,3 +753,78 @@ type BarLookup = typeof BAR_LOOKUP; type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] }; >Baz : { a: "a"; b: "b"; } +// repro from #43982 + +interface Original { + prop1: { +>prop1 : { subProp1: string; subProp2: string; } + + subProp1: string; +>subProp1 : string + + subProp2: string; +>subProp2 : string + + }; + prop2: { +>prop2 : { subProp3: string; subProp4: string; } + + subProp3: string; +>subProp3 : string + + subProp4: string; +>subProp4 : string + + }; +} +type KeyOfOriginal = keyof Original; +>KeyOfOriginal : keyof Original + +type NestedKeyOfOriginalFor = keyof Original[T]; +>NestedKeyOfOriginalFor : keyof Original[T] + +type SameKeys = { +>SameKeys : SameKeys + + [K in keyof T]: { + [K2 in keyof T[K]]: number; + }; +}; + +type MappedFromOriginal = SameKeys; +>MappedFromOriginal : SameKeys + +const getStringAndNumberFromOriginalAndMapped = < +>getStringAndNumberFromOriginalAndMapped : (original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N) => [Original[K][N], SameKeys[K][N]] +>< K extends KeyOfOriginal, N extends NestedKeyOfOriginalFor>( original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N): [Original[K][N], MappedFromOriginal[K][N]] => { return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];} : (original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N) => [Original[K][N], SameKeys[K][N]] + + K extends KeyOfOriginal, + N extends NestedKeyOfOriginalFor +>( + original: Original, +>original : Original + + mappedFromOriginal: MappedFromOriginal, +>mappedFromOriginal : SameKeys + + key: K, +>key : K + + nestedKey: N +>nestedKey : N + +): [Original[K][N], MappedFromOriginal[K][N]] => { + return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]]; +>[original[key][nestedKey], mappedFromOriginal[key][nestedKey]] : [Original[K][N], SameKeys[K][N]] +>original[key][nestedKey] : Original[K][N] +>original[key] : Original[K] +>original : Original +>key : K +>nestedKey : N +>mappedFromOriginal[key][nestedKey] : SameKeys[K][N] +>mappedFromOriginal[key] : SameKeys[K] +>mappedFromOriginal : SameKeys +>key : K +>nestedKey : N + +}; diff --git a/tests/cases/compiler/correlatedUnions.ts b/tests/cases/compiler/correlatedUnions.ts index e75e56f15ce69..26ceee428de27 100644 --- a/tests/cases/compiler/correlatedUnions.ts +++ b/tests/cases/compiler/correlatedUnions.ts @@ -176,7 +176,7 @@ function f2(funcs: Funcs, key: K, arg: ArgMap[K]) { } function f3(funcs: Funcs, key: K, arg: ArgMap[K]) { - const func: Func = funcs[key]; // Error, Funcs[K] not assignable to Func + const func: Func = funcs[key]; func(arg); } @@ -236,3 +236,38 @@ const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name'); type BarLookup = typeof BAR_LOOKUP; type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] }; + +// repro from #43982 + +interface Original { + prop1: { + subProp1: string; + subProp2: string; + }; + prop2: { + subProp3: string; + subProp4: string; + }; +} +type KeyOfOriginal = keyof Original; +type NestedKeyOfOriginalFor = keyof Original[T]; + +type SameKeys = { + [K in keyof T]: { + [K2 in keyof T[K]]: number; + }; +}; + +type MappedFromOriginal = SameKeys; + +const getStringAndNumberFromOriginalAndMapped = < + K extends KeyOfOriginal, + N extends NestedKeyOfOriginalFor +>( + original: Original, + mappedFromOriginal: MappedFromOriginal, + key: K, + nestedKey: N +): [Original[K][N], MappedFromOriginal[K][N]] => { + return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]]; +}; \ No newline at end of file