Skip to content

Commit 32da8a2

Browse files
authored
Add a test for indexed access on generic mapped type (#52069)
1 parent 48b6b8b commit 32da8a2

File tree

4 files changed

+276
-6
lines changed

4 files changed

+276
-6
lines changed

tests/baselines/reference/correlatedUnions.js

+59-3
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ function f2<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
174174
}
175175

176176
function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
177-
const func: Func<K> = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
177+
const func: Func<K> = funcs[key];
178178
func(arg);
179179
}
180180

@@ -234,7 +234,41 @@ const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
234234
type BarLookup = typeof BAR_LOOKUP;
235235

236236
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
237-
237+
238+
// repro from #43982
239+
240+
interface Original {
241+
prop1: {
242+
subProp1: string;
243+
subProp2: string;
244+
};
245+
prop2: {
246+
subProp3: string;
247+
subProp4: string;
248+
};
249+
}
250+
type KeyOfOriginal = keyof Original;
251+
type NestedKeyOfOriginalFor<T extends KeyOfOriginal> = keyof Original[T];
252+
253+
type SameKeys<T> = {
254+
[K in keyof T]: {
255+
[K2 in keyof T[K]]: number;
256+
};
257+
};
258+
259+
type MappedFromOriginal = SameKeys<Original>;
260+
261+
const getStringAndNumberFromOriginalAndMapped = <
262+
K extends KeyOfOriginal,
263+
N extends NestedKeyOfOriginalFor<K>
264+
>(
265+
original: Original,
266+
mappedFromOriginal: MappedFromOriginal,
267+
key: K,
268+
nestedKey: N
269+
): [Original[K][N], MappedFromOriginal[K][N]] => {
270+
return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];
271+
};
238272

239273
//// [correlatedUnions.js]
240274
"use strict";
@@ -329,7 +363,7 @@ function f2(funcs, key, arg) {
329363
func(arg);
330364
}
331365
function f3(funcs, key, arg) {
332-
var func = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
366+
var func = funcs[key];
333367
func(arg);
334368
}
335369
function f4(x, y) {
@@ -355,6 +389,9 @@ function foo(prop, f) {
355389
}
356390
var ALL_BARS = [{ name: 'a' }, { name: 'b' }];
357391
var BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
392+
var getStringAndNumberFromOriginalAndMapped = function (original, mappedFromOriginal, key, nestedKey) {
393+
return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];
394+
};
358395

359396

360397
//// [correlatedUnions.d.ts]
@@ -506,3 +543,22 @@ type BarLookup = typeof BAR_LOOKUP;
506543
type Baz = {
507544
[K in keyof BarLookup]: BarLookup[K]['name'];
508545
};
546+
interface Original {
547+
prop1: {
548+
subProp1: string;
549+
subProp2: string;
550+
};
551+
prop2: {
552+
subProp3: string;
553+
subProp4: string;
554+
};
555+
}
556+
type KeyOfOriginal = keyof Original;
557+
type NestedKeyOfOriginalFor<T extends KeyOfOriginal> = keyof Original[T];
558+
type SameKeys<T> = {
559+
[K in keyof T]: {
560+
[K2 in keyof T[K]]: number;
561+
};
562+
};
563+
type MappedFromOriginal = SameKeys<Original>;
564+
declare const getStringAndNumberFromOriginalAndMapped: <K extends keyof Original, N extends keyof Original[K]>(original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N) => [Original[K][N], SameKeys<Original>[K][N]];

tests/baselines/reference/correlatedUnions.symbols

+105-1
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
647647
>ArgMap : Symbol(ArgMap, Decl(correlatedUnions.ts, 157, 1))
648648
>K : Symbol(K, Decl(correlatedUnions.ts, 174, 12))
649649

650-
const func: Func<K> = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
650+
const func: Func<K> = funcs[key];
651651
>func : Symbol(func, Decl(correlatedUnions.ts, 175, 9))
652652
>Func : Symbol(Func, Decl(correlatedUnions.ts, 161, 39))
653653
>K : Symbol(K, Decl(correlatedUnions.ts, 174, 12))
@@ -824,3 +824,107 @@ type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
824824
>BarLookup : Symbol(BarLookup, Decl(correlatedUnions.ts, 230, 63))
825825
>K : Symbol(K, Decl(correlatedUnions.ts, 234, 14))
826826

827+
// repro from #43982
828+
829+
interface Original {
830+
>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60))
831+
832+
prop1: {
833+
>prop1 : Symbol(Original.prop1, Decl(correlatedUnions.ts, 238, 20))
834+
835+
subProp1: string;
836+
>subProp1 : Symbol(subProp1, Decl(correlatedUnions.ts, 239, 10))
837+
838+
subProp2: string;
839+
>subProp2 : Symbol(subProp2, Decl(correlatedUnions.ts, 240, 21))
840+
841+
};
842+
prop2: {
843+
>prop2 : Symbol(Original.prop2, Decl(correlatedUnions.ts, 242, 4))
844+
845+
subProp3: string;
846+
>subProp3 : Symbol(subProp3, Decl(correlatedUnions.ts, 243, 10))
847+
848+
subProp4: string;
849+
>subProp4 : Symbol(subProp4, Decl(correlatedUnions.ts, 244, 21))
850+
851+
};
852+
}
853+
type KeyOfOriginal = keyof Original;
854+
>KeyOfOriginal : Symbol(KeyOfOriginal, Decl(correlatedUnions.ts, 247, 1))
855+
>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60))
856+
857+
type NestedKeyOfOriginalFor<T extends KeyOfOriginal> = keyof Original[T];
858+
>NestedKeyOfOriginalFor : Symbol(NestedKeyOfOriginalFor, Decl(correlatedUnions.ts, 248, 36))
859+
>T : Symbol(T, Decl(correlatedUnions.ts, 249, 28))
860+
>KeyOfOriginal : Symbol(KeyOfOriginal, Decl(correlatedUnions.ts, 247, 1))
861+
>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60))
862+
>T : Symbol(T, Decl(correlatedUnions.ts, 249, 28))
863+
864+
type SameKeys<T> = {
865+
>SameKeys : Symbol(SameKeys, Decl(correlatedUnions.ts, 249, 73))
866+
>T : Symbol(T, Decl(correlatedUnions.ts, 251, 14))
867+
868+
[K in keyof T]: {
869+
>K : Symbol(K, Decl(correlatedUnions.ts, 252, 3))
870+
>T : Symbol(T, Decl(correlatedUnions.ts, 251, 14))
871+
872+
[K2 in keyof T[K]]: number;
873+
>K2 : Symbol(K2, Decl(correlatedUnions.ts, 253, 5))
874+
>T : Symbol(T, Decl(correlatedUnions.ts, 251, 14))
875+
>K : Symbol(K, Decl(correlatedUnions.ts, 252, 3))
876+
877+
};
878+
};
879+
880+
type MappedFromOriginal = SameKeys<Original>;
881+
>MappedFromOriginal : Symbol(MappedFromOriginal, Decl(correlatedUnions.ts, 255, 2))
882+
>SameKeys : Symbol(SameKeys, Decl(correlatedUnions.ts, 249, 73))
883+
>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60))
884+
885+
const getStringAndNumberFromOriginalAndMapped = <
886+
>getStringAndNumberFromOriginalAndMapped : Symbol(getStringAndNumberFromOriginalAndMapped, Decl(correlatedUnions.ts, 259, 5))
887+
888+
K extends KeyOfOriginal,
889+
>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49))
890+
>KeyOfOriginal : Symbol(KeyOfOriginal, Decl(correlatedUnions.ts, 247, 1))
891+
892+
N extends NestedKeyOfOriginalFor<K>
893+
>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26))
894+
>NestedKeyOfOriginalFor : Symbol(NestedKeyOfOriginalFor, Decl(correlatedUnions.ts, 248, 36))
895+
>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49))
896+
897+
>(
898+
original: Original,
899+
>original : Symbol(original, Decl(correlatedUnions.ts, 262, 2))
900+
>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60))
901+
902+
mappedFromOriginal: MappedFromOriginal,
903+
>mappedFromOriginal : Symbol(mappedFromOriginal, Decl(correlatedUnions.ts, 263, 21))
904+
>MappedFromOriginal : Symbol(MappedFromOriginal, Decl(correlatedUnions.ts, 255, 2))
905+
906+
key: K,
907+
>key : Symbol(key, Decl(correlatedUnions.ts, 264, 41))
908+
>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49))
909+
910+
nestedKey: N
911+
>nestedKey : Symbol(nestedKey, Decl(correlatedUnions.ts, 265, 9))
912+
>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26))
913+
914+
): [Original[K][N], MappedFromOriginal[K][N]] => {
915+
>Original : Symbol(Original, Decl(correlatedUnions.ts, 234, 60))
916+
>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49))
917+
>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26))
918+
>MappedFromOriginal : Symbol(MappedFromOriginal, Decl(correlatedUnions.ts, 255, 2))
919+
>K : Symbol(K, Decl(correlatedUnions.ts, 259, 49))
920+
>N : Symbol(N, Decl(correlatedUnions.ts, 260, 26))
921+
922+
return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];
923+
>original : Symbol(original, Decl(correlatedUnions.ts, 262, 2))
924+
>key : Symbol(key, Decl(correlatedUnions.ts, 264, 41))
925+
>nestedKey : Symbol(nestedKey, Decl(correlatedUnions.ts, 265, 9))
926+
>mappedFromOriginal : Symbol(mappedFromOriginal, Decl(correlatedUnions.ts, 263, 21))
927+
>key : Symbol(key, Decl(correlatedUnions.ts, 264, 41))
928+
>nestedKey : Symbol(nestedKey, Decl(correlatedUnions.ts, 265, 9))
929+
930+
};

tests/baselines/reference/correlatedUnions.types

+76-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
601601
>key : K
602602
>arg : ArgMap[K]
603603

604-
const func: Func<K> = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
604+
const func: Func<K> = funcs[key];
605605
>func : Func<K>
606606
>funcs[key] : Funcs[K]
607607
>funcs : Funcs
@@ -753,3 +753,78 @@ type BarLookup = typeof BAR_LOOKUP;
753753
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
754754
>Baz : { a: "a"; b: "b"; }
755755

756+
// repro from #43982
757+
758+
interface Original {
759+
prop1: {
760+
>prop1 : { subProp1: string; subProp2: string; }
761+
762+
subProp1: string;
763+
>subProp1 : string
764+
765+
subProp2: string;
766+
>subProp2 : string
767+
768+
};
769+
prop2: {
770+
>prop2 : { subProp3: string; subProp4: string; }
771+
772+
subProp3: string;
773+
>subProp3 : string
774+
775+
subProp4: string;
776+
>subProp4 : string
777+
778+
};
779+
}
780+
type KeyOfOriginal = keyof Original;
781+
>KeyOfOriginal : keyof Original
782+
783+
type NestedKeyOfOriginalFor<T extends KeyOfOriginal> = keyof Original[T];
784+
>NestedKeyOfOriginalFor : keyof Original[T]
785+
786+
type SameKeys<T> = {
787+
>SameKeys : SameKeys<T>
788+
789+
[K in keyof T]: {
790+
[K2 in keyof T[K]]: number;
791+
};
792+
};
793+
794+
type MappedFromOriginal = SameKeys<Original>;
795+
>MappedFromOriginal : SameKeys<Original>
796+
797+
const getStringAndNumberFromOriginalAndMapped = <
798+
>getStringAndNumberFromOriginalAndMapped : <K extends keyof Original, N extends keyof Original[K]>(original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N) => [Original[K][N], SameKeys<Original>[K][N]]
799+
>< K extends KeyOfOriginal, N extends NestedKeyOfOriginalFor<K>>( original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N): [Original[K][N], MappedFromOriginal[K][N]] => { return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];} : <K extends keyof Original, N extends keyof Original[K]>(original: Original, mappedFromOriginal: MappedFromOriginal, key: K, nestedKey: N) => [Original[K][N], SameKeys<Original>[K][N]]
800+
801+
K extends KeyOfOriginal,
802+
N extends NestedKeyOfOriginalFor<K>
803+
>(
804+
original: Original,
805+
>original : Original
806+
807+
mappedFromOriginal: MappedFromOriginal,
808+
>mappedFromOriginal : SameKeys<Original>
809+
810+
key: K,
811+
>key : K
812+
813+
nestedKey: N
814+
>nestedKey : N
815+
816+
): [Original[K][N], MappedFromOriginal[K][N]] => {
817+
return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];
818+
>[original[key][nestedKey], mappedFromOriginal[key][nestedKey]] : [Original[K][N], SameKeys<Original>[K][N]]
819+
>original[key][nestedKey] : Original[K][N]
820+
>original[key] : Original[K]
821+
>original : Original
822+
>key : K
823+
>nestedKey : N
824+
>mappedFromOriginal[key][nestedKey] : SameKeys<Original>[K][N]
825+
>mappedFromOriginal[key] : SameKeys<Original>[K]
826+
>mappedFromOriginal : SameKeys<Original>
827+
>key : K
828+
>nestedKey : N
829+
830+
};

tests/cases/compiler/correlatedUnions.ts

+36-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ function f2<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
176176
}
177177

178178
function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
179-
const func: Func<K> = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
179+
const func: Func<K> = funcs[key];
180180
func(arg);
181181
}
182182

@@ -236,3 +236,38 @@ const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
236236
type BarLookup = typeof BAR_LOOKUP;
237237

238238
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
239+
240+
// repro from #43982
241+
242+
interface Original {
243+
prop1: {
244+
subProp1: string;
245+
subProp2: string;
246+
};
247+
prop2: {
248+
subProp3: string;
249+
subProp4: string;
250+
};
251+
}
252+
type KeyOfOriginal = keyof Original;
253+
type NestedKeyOfOriginalFor<T extends KeyOfOriginal> = keyof Original[T];
254+
255+
type SameKeys<T> = {
256+
[K in keyof T]: {
257+
[K2 in keyof T[K]]: number;
258+
};
259+
};
260+
261+
type MappedFromOriginal = SameKeys<Original>;
262+
263+
const getStringAndNumberFromOriginalAndMapped = <
264+
K extends KeyOfOriginal,
265+
N extends NestedKeyOfOriginalFor<K>
266+
>(
267+
original: Original,
268+
mappedFromOriginal: MappedFromOriginal,
269+
key: K,
270+
nestedKey: N
271+
): [Original[K][N], MappedFromOriginal[K][N]] => {
272+
return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]];
273+
};

0 commit comments

Comments
 (0)