Skip to content

Commit

Permalink
Add a test for indexed access on generic mapped type (#52069)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist authored Jan 10, 2023
1 parent 48b6b8b commit 32da8a2
Show file tree
Hide file tree
Showing 4 changed files with 276 additions and 6 deletions.
62 changes: 59 additions & 3 deletions tests/baselines/reference/correlatedUnions.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function f2<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
}

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

Expand Down Expand Up @@ -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<T extends KeyOfOriginal> = keyof Original[T];

type SameKeys<T> = {
[K in keyof T]: {
[K2 in keyof T[K]]: number;
};
};

type MappedFromOriginal = SameKeys<Original>;

const getStringAndNumberFromOriginalAndMapped = <
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]];
};

//// [correlatedUnions.js]
"use strict";
Expand Down Expand Up @@ -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<K>
var func = funcs[key];
func(arg);
}
function f4(x, y) {
Expand All @@ -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]
Expand Down Expand Up @@ -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<T extends KeyOfOriginal> = keyof Original[T];
type SameKeys<T> = {
[K in keyof T]: {
[K2 in keyof T[K]]: number;
};
};
type MappedFromOriginal = SameKeys<Original>;
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]];
106 changes: 105 additions & 1 deletion tests/baselines/reference/correlatedUnions.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ function f3<K extends keyof ArgMap>(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<K> = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
const func: Func<K> = 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))
Expand Down Expand Up @@ -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<T extends KeyOfOriginal> = 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<T> = {
>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<Original>;
>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<K>
>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))

};
77 changes: 76 additions & 1 deletion tests/baselines/reference/correlatedUnions.types
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
>key : K
>arg : ArgMap[K]

const func: Func<K> = funcs[key]; // Error, Funcs[K] not assignable to Func<K>
const func: Func<K> = funcs[key];
>func : Func<K>
>funcs[key] : Funcs[K]
>funcs : Funcs
Expand Down Expand Up @@ -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<T extends KeyOfOriginal> = keyof Original[T];
>NestedKeyOfOriginalFor : keyof Original[T]

type SameKeys<T> = {
>SameKeys : SameKeys<T>

[K in keyof T]: {
[K2 in keyof T[K]]: number;
};
};

type MappedFromOriginal = SameKeys<Original>;
>MappedFromOriginal : SameKeys<Original>

const getStringAndNumberFromOriginalAndMapped = <
>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]]
>< 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]]

K extends KeyOfOriginal,
N extends NestedKeyOfOriginalFor<K>
>(
original: Original,
>original : Original

mappedFromOriginal: MappedFromOriginal,
>mappedFromOriginal : SameKeys<Original>

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<Original>[K][N]]
>original[key][nestedKey] : Original[K][N]
>original[key] : Original[K]
>original : Original
>key : K
>nestedKey : N
>mappedFromOriginal[key][nestedKey] : SameKeys<Original>[K][N]
>mappedFromOriginal[key] : SameKeys<Original>[K]
>mappedFromOriginal : SameKeys<Original>
>key : K
>nestedKey : N

};
37 changes: 36 additions & 1 deletion tests/cases/compiler/correlatedUnions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function f2<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
}

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

Expand Down Expand Up @@ -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<T extends KeyOfOriginal> = keyof Original[T];

type SameKeys<T> = {
[K in keyof T]: {
[K2 in keyof T[K]]: number;
};
};

type MappedFromOriginal = SameKeys<Original>;

const getStringAndNumberFromOriginalAndMapped = <
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]];
};

0 comments on commit 32da8a2

Please sign in to comment.