Skip to content

Commit 6c6f216

Browse files
mattmccutchenweswigham
authored andcommitted
Handle generic mapped types in getTypeOfPropertyOfContextualType. (#27586)
* Handle generic mapped types in getTypeOfPropertyOfContextualType. The changes to existing baselines look acceptable to me. Fixes #24694. * Minor reorganization, add test case from @yortus
1 parent d247675 commit 6c6f216

10 files changed

+392
-7
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10017,13 +10017,17 @@ namespace ts {
1001710017
// that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
1001810018
// construct the type Box<T[X]>.
1001910019
if (isGenericMappedType(objectType)) {
10020-
const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]);
10021-
const templateMapper = combineTypeMappers(objectType.mapper, mapper);
10022-
return type.simplified = mapType(instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper), getSimplifiedType);
10020+
return type.simplified = mapType(substituteIndexedMappedType(objectType, type.indexType), getSimplifiedType);
1002310021
}
1002410022
return type.simplified = type;
1002510023
}
1002610024

10025+
function substituteIndexedMappedType(objectType: MappedType, index: Type) {
10026+
const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
10027+
const templateMapper = combineTypeMappers(objectType.mapper, mapper);
10028+
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
10029+
}
10030+
1002710031
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, missingType = accessNode ? errorType : unknownType): Type {
1002810032
if (objectType === wildcardType || indexType === wildcardType) {
1002910033
return wildcardType;
@@ -17831,7 +17835,15 @@ namespace ts {
1783117835

1783217836
function getTypeOfPropertyOfContextualType(type: Type, name: __String) {
1783317837
return mapType(type, t => {
17834-
if (t.flags & TypeFlags.StructuredType) {
17838+
if (isGenericMappedType(t)) {
17839+
const constraint = getConstraintTypeFromMappedType(t);
17840+
const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
17841+
const propertyNameType = getLiteralType(unescapeLeadingUnderscores(name));
17842+
if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
17843+
return substituteIndexedMappedType(t, propertyNameType);
17844+
}
17845+
}
17846+
else if (t.flags & TypeFlags.StructuredType) {
1783517847
const prop = getPropertyOfType(t, name);
1783617848
if (prop) {
1783717849
return getTypeOfSymbol(prop);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [contextualPropertyOfGenericMappedType.ts]
2+
// Repro for #24694
3+
4+
declare function f<T extends object>(data: T, handlers: { [P in keyof T]: (value: T[P], prop: P) => void; }): void;
5+
f({ data: 0 }, { data(value, key) {} });
6+
7+
8+
//// [contextualPropertyOfGenericMappedType.js]
9+
// Repro for #24694
10+
f({ data: 0 }, { data: function (value, key) { } });
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/compiler/contextualPropertyOfGenericMappedType.ts ===
2+
// Repro for #24694
3+
4+
declare function f<T extends object>(data: T, handlers: { [P in keyof T]: (value: T[P], prop: P) => void; }): void;
5+
>f : Symbol(f, Decl(contextualPropertyOfGenericMappedType.ts, 0, 0))
6+
>T : Symbol(T, Decl(contextualPropertyOfGenericMappedType.ts, 2, 19))
7+
>data : Symbol(data, Decl(contextualPropertyOfGenericMappedType.ts, 2, 37))
8+
>T : Symbol(T, Decl(contextualPropertyOfGenericMappedType.ts, 2, 19))
9+
>handlers : Symbol(handlers, Decl(contextualPropertyOfGenericMappedType.ts, 2, 45))
10+
>P : Symbol(P, Decl(contextualPropertyOfGenericMappedType.ts, 2, 59))
11+
>T : Symbol(T, Decl(contextualPropertyOfGenericMappedType.ts, 2, 19))
12+
>value : Symbol(value, Decl(contextualPropertyOfGenericMappedType.ts, 2, 75))
13+
>T : Symbol(T, Decl(contextualPropertyOfGenericMappedType.ts, 2, 19))
14+
>P : Symbol(P, Decl(contextualPropertyOfGenericMappedType.ts, 2, 59))
15+
>prop : Symbol(prop, Decl(contextualPropertyOfGenericMappedType.ts, 2, 87))
16+
>P : Symbol(P, Decl(contextualPropertyOfGenericMappedType.ts, 2, 59))
17+
18+
f({ data: 0 }, { data(value, key) {} });
19+
>f : Symbol(f, Decl(contextualPropertyOfGenericMappedType.ts, 0, 0))
20+
>data : Symbol(data, Decl(contextualPropertyOfGenericMappedType.ts, 3, 3))
21+
>data : Symbol(data, Decl(contextualPropertyOfGenericMappedType.ts, 3, 16))
22+
>value : Symbol(value, Decl(contextualPropertyOfGenericMappedType.ts, 3, 22))
23+
>key : Symbol(key, Decl(contextualPropertyOfGenericMappedType.ts, 3, 28))
24+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/compiler/contextualPropertyOfGenericMappedType.ts ===
2+
// Repro for #24694
3+
4+
declare function f<T extends object>(data: T, handlers: { [P in keyof T]: (value: T[P], prop: P) => void; }): void;
5+
>f : <T extends object>(data: T, handlers: { [P in keyof T]: (value: T[P], prop: P) => void; }) => void
6+
>data : T
7+
>handlers : { [P in keyof T]: (value: T[P], prop: P) => void; }
8+
>value : T[P]
9+
>prop : P
10+
11+
f({ data: 0 }, { data(value, key) {} });
12+
>f({ data: 0 }, { data(value, key) {} }) : void
13+
>f : <T extends object>(data: T, handlers: { [P in keyof T]: (value: T[P], prop: P) => void; }) => void
14+
>{ data: 0 } : { data: number; }
15+
>data : number
16+
>0 : 0
17+
>{ data(value, key) {} } : { data(value: number, key: "data"): void; }
18+
>data : (value: number, key: "data") => void
19+
>value : number
20+
>key : "data"
21+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [mappedTypeContextualTypesApplied.ts]
2+
type TakeString = (s: string) => any;
3+
4+
// Various functions accepting an object whose properties are TakeString functions.
5+
// Note these all use mapped types.
6+
declare function mapped1<T extends {[P in string]: TakeString}>(obj: T): void;
7+
declare function mapped2<T extends {[P in keyof T]: TakeString}>(obj: T): void;
8+
declare function mapped3<T extends {[P in keyof any]: TakeString}>(obj: T): void;
9+
declare function mapped4<T>(obj: T & {[P in keyof T]: TakeString}): void;
10+
declare function mapped5<T, K extends keyof T>(obj: T & {[P in K]: TakeString}): void;
11+
declare function mapped6<K extends string>(obj: {[P in K]: TakeString}): void;
12+
declare function mapped7<K extends keyof any>(obj: {[P in K]: TakeString}): void;
13+
declare function mapped8<K extends 'foo'>(obj: {[P in K]: TakeString}): void;
14+
declare function mapped9<K extends 'foo'|'bar'>(obj: {[P in K]: TakeString}): void;
15+
16+
mapped1({foo: s => 42});
17+
mapped2({foo: s => 42});
18+
mapped3({foo: s => 42});
19+
mapped4({foo: s => 42});
20+
mapped5({foo: s => 42});
21+
mapped6({foo: s => 42});
22+
mapped7({foo: s => 42});
23+
mapped8({foo: s => 42});
24+
mapped9({foo: s => 42});
25+
26+
//// [mappedTypeContextualTypesApplied.js]
27+
"use strict";
28+
mapped1({ foo: function (s) { return 42; } });
29+
mapped2({ foo: function (s) { return 42; } });
30+
mapped3({ foo: function (s) { return 42; } });
31+
mapped4({ foo: function (s) { return 42; } });
32+
mapped5({ foo: function (s) { return 42; } });
33+
mapped6({ foo: function (s) { return 42; } });
34+
mapped7({ foo: function (s) { return 42; } });
35+
mapped8({ foo: function (s) { return 42; } });
36+
mapped9({ foo: function (s) { return 42; } });
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
=== tests/cases/compiler/mappedTypeContextualTypesApplied.ts ===
2+
type TakeString = (s: string) => any;
3+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
4+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 0, 19))
5+
6+
// Various functions accepting an object whose properties are TakeString functions.
7+
// Note these all use mapped types.
8+
declare function mapped1<T extends {[P in string]: TakeString}>(obj: T): void;
9+
>mapped1 : Symbol(mapped1, Decl(mappedTypeContextualTypesApplied.ts, 0, 37))
10+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 4, 25))
11+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 4, 37))
12+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
13+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 4, 64))
14+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 4, 25))
15+
16+
declare function mapped2<T extends {[P in keyof T]: TakeString}>(obj: T): void;
17+
>mapped2 : Symbol(mapped2, Decl(mappedTypeContextualTypesApplied.ts, 4, 78))
18+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 5, 25))
19+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 5, 37))
20+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 5, 25))
21+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
22+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 5, 65))
23+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 5, 25))
24+
25+
declare function mapped3<T extends {[P in keyof any]: TakeString}>(obj: T): void;
26+
>mapped3 : Symbol(mapped3, Decl(mappedTypeContextualTypesApplied.ts, 5, 79))
27+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 6, 25))
28+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 6, 37))
29+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
30+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 6, 67))
31+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 6, 25))
32+
33+
declare function mapped4<T>(obj: T & {[P in keyof T]: TakeString}): void;
34+
>mapped4 : Symbol(mapped4, Decl(mappedTypeContextualTypesApplied.ts, 6, 81))
35+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 7, 25))
36+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 7, 28))
37+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 7, 25))
38+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 7, 39))
39+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 7, 25))
40+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
41+
42+
declare function mapped5<T, K extends keyof T>(obj: T & {[P in K]: TakeString}): void;
43+
>mapped5 : Symbol(mapped5, Decl(mappedTypeContextualTypesApplied.ts, 7, 73))
44+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 8, 25))
45+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 8, 27))
46+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 8, 25))
47+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 8, 47))
48+
>T : Symbol(T, Decl(mappedTypeContextualTypesApplied.ts, 8, 25))
49+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 8, 58))
50+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 8, 27))
51+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
52+
53+
declare function mapped6<K extends string>(obj: {[P in K]: TakeString}): void;
54+
>mapped6 : Symbol(mapped6, Decl(mappedTypeContextualTypesApplied.ts, 8, 86))
55+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 9, 25))
56+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 9, 43))
57+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 9, 50))
58+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 9, 25))
59+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
60+
61+
declare function mapped7<K extends keyof any>(obj: {[P in K]: TakeString}): void;
62+
>mapped7 : Symbol(mapped7, Decl(mappedTypeContextualTypesApplied.ts, 9, 78))
63+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 10, 25))
64+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 10, 46))
65+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 10, 53))
66+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 10, 25))
67+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
68+
69+
declare function mapped8<K extends 'foo'>(obj: {[P in K]: TakeString}): void;
70+
>mapped8 : Symbol(mapped8, Decl(mappedTypeContextualTypesApplied.ts, 10, 81))
71+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 11, 25))
72+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 11, 42))
73+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 11, 49))
74+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 11, 25))
75+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
76+
77+
declare function mapped9<K extends 'foo'|'bar'>(obj: {[P in K]: TakeString}): void;
78+
>mapped9 : Symbol(mapped9, Decl(mappedTypeContextualTypesApplied.ts, 11, 77))
79+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 12, 25))
80+
>obj : Symbol(obj, Decl(mappedTypeContextualTypesApplied.ts, 12, 48))
81+
>P : Symbol(P, Decl(mappedTypeContextualTypesApplied.ts, 12, 55))
82+
>K : Symbol(K, Decl(mappedTypeContextualTypesApplied.ts, 12, 25))
83+
>TakeString : Symbol(TakeString, Decl(mappedTypeContextualTypesApplied.ts, 0, 0))
84+
85+
mapped1({foo: s => 42});
86+
>mapped1 : Symbol(mapped1, Decl(mappedTypeContextualTypesApplied.ts, 0, 37))
87+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 14, 9))
88+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 14, 13))
89+
90+
mapped2({foo: s => 42});
91+
>mapped2 : Symbol(mapped2, Decl(mappedTypeContextualTypesApplied.ts, 4, 78))
92+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 15, 9))
93+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 15, 13))
94+
95+
mapped3({foo: s => 42});
96+
>mapped3 : Symbol(mapped3, Decl(mappedTypeContextualTypesApplied.ts, 5, 79))
97+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 16, 9))
98+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 16, 13))
99+
100+
mapped4({foo: s => 42});
101+
>mapped4 : Symbol(mapped4, Decl(mappedTypeContextualTypesApplied.ts, 6, 81))
102+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 17, 9))
103+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 17, 13))
104+
105+
mapped5({foo: s => 42});
106+
>mapped5 : Symbol(mapped5, Decl(mappedTypeContextualTypesApplied.ts, 7, 73))
107+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 18, 9))
108+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 18, 13))
109+
110+
mapped6({foo: s => 42});
111+
>mapped6 : Symbol(mapped6, Decl(mappedTypeContextualTypesApplied.ts, 8, 86))
112+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 19, 9))
113+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 19, 13))
114+
115+
mapped7({foo: s => 42});
116+
>mapped7 : Symbol(mapped7, Decl(mappedTypeContextualTypesApplied.ts, 9, 78))
117+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 20, 9))
118+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 20, 13))
119+
120+
mapped8({foo: s => 42});
121+
>mapped8 : Symbol(mapped8, Decl(mappedTypeContextualTypesApplied.ts, 10, 81))
122+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 21, 9))
123+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 21, 13))
124+
125+
mapped9({foo: s => 42});
126+
>mapped9 : Symbol(mapped9, Decl(mappedTypeContextualTypesApplied.ts, 11, 77))
127+
>foo : Symbol(foo, Decl(mappedTypeContextualTypesApplied.ts, 22, 9))
128+
>s : Symbol(s, Decl(mappedTypeContextualTypesApplied.ts, 22, 13))
129+
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
=== tests/cases/compiler/mappedTypeContextualTypesApplied.ts ===
2+
type TakeString = (s: string) => any;
3+
>TakeString : TakeString
4+
>s : string
5+
6+
// Various functions accepting an object whose properties are TakeString functions.
7+
// Note these all use mapped types.
8+
declare function mapped1<T extends {[P in string]: TakeString}>(obj: T): void;
9+
>mapped1 : <T extends { [x: string]: TakeString; }>(obj: T) => void
10+
>obj : T
11+
12+
declare function mapped2<T extends {[P in keyof T]: TakeString}>(obj: T): void;
13+
>mapped2 : <T extends { [P in keyof T]: TakeString; }>(obj: T) => void
14+
>obj : T
15+
16+
declare function mapped3<T extends {[P in keyof any]: TakeString}>(obj: T): void;
17+
>mapped3 : <T extends { [x: string]: TakeString; }>(obj: T) => void
18+
>obj : T
19+
20+
declare function mapped4<T>(obj: T & {[P in keyof T]: TakeString}): void;
21+
>mapped4 : <T>(obj: T & { [P in keyof T]: TakeString; }) => void
22+
>obj : T & { [P in keyof T]: TakeString; }
23+
24+
declare function mapped5<T, K extends keyof T>(obj: T & {[P in K]: TakeString}): void;
25+
>mapped5 : <T, K extends keyof T>(obj: T & { [P in K]: TakeString; }) => void
26+
>obj : T & { [P in K]: TakeString; }
27+
28+
declare function mapped6<K extends string>(obj: {[P in K]: TakeString}): void;
29+
>mapped6 : <K extends string>(obj: { [P in K]: TakeString; }) => void
30+
>obj : { [P in K]: TakeString; }
31+
32+
declare function mapped7<K extends keyof any>(obj: {[P in K]: TakeString}): void;
33+
>mapped7 : <K extends string | number | symbol>(obj: { [P in K]: TakeString; }) => void
34+
>obj : { [P in K]: TakeString; }
35+
36+
declare function mapped8<K extends 'foo'>(obj: {[P in K]: TakeString}): void;
37+
>mapped8 : <K extends "foo">(obj: { [P in K]: TakeString; }) => void
38+
>obj : { [P in K]: TakeString; }
39+
40+
declare function mapped9<K extends 'foo'|'bar'>(obj: {[P in K]: TakeString}): void;
41+
>mapped9 : <K extends "foo" | "bar">(obj: { [P in K]: TakeString; }) => void
42+
>obj : { [P in K]: TakeString; }
43+
44+
mapped1({foo: s => 42});
45+
>mapped1({foo: s => 42}) : void
46+
>mapped1 : <T extends { [x: string]: TakeString; }>(obj: T) => void
47+
>{foo: s => 42} : { foo: (s: string) => number; }
48+
>foo : (s: string) => number
49+
>s => 42 : (s: string) => number
50+
>s : string
51+
>42 : 42
52+
53+
mapped2({foo: s => 42});
54+
>mapped2({foo: s => 42}) : void
55+
>mapped2 : <T extends { [P in keyof T]: TakeString; }>(obj: T) => void
56+
>{foo: s => 42} : { foo: (s: string) => number; }
57+
>foo : (s: string) => number
58+
>s => 42 : (s: string) => number
59+
>s : string
60+
>42 : 42
61+
62+
mapped3({foo: s => 42});
63+
>mapped3({foo: s => 42}) : void
64+
>mapped3 : <T extends { [x: string]: TakeString; }>(obj: T) => void
65+
>{foo: s => 42} : { foo: (s: string) => number; }
66+
>foo : (s: string) => number
67+
>s => 42 : (s: string) => number
68+
>s : string
69+
>42 : 42
70+
71+
mapped4({foo: s => 42});
72+
>mapped4({foo: s => 42}) : void
73+
>mapped4 : <T>(obj: T & { [P in keyof T]: TakeString; }) => void
74+
>{foo: s => 42} : { foo: (s: string) => number; }
75+
>foo : (s: string) => number
76+
>s => 42 : (s: string) => number
77+
>s : string
78+
>42 : 42
79+
80+
mapped5({foo: s => 42});
81+
>mapped5({foo: s => 42}) : void
82+
>mapped5 : <T, K extends keyof T>(obj: T & { [P in K]: TakeString; }) => void
83+
>{foo: s => 42} : { foo: (s: string) => number; }
84+
>foo : (s: string) => number
85+
>s => 42 : (s: string) => number
86+
>s : string
87+
>42 : 42
88+
89+
mapped6({foo: s => 42});
90+
>mapped6({foo: s => 42}) : void
91+
>mapped6 : <K extends string>(obj: { [P in K]: TakeString; }) => void
92+
>{foo: s => 42} : { foo: (s: string) => number; }
93+
>foo : (s: string) => number
94+
>s => 42 : (s: string) => number
95+
>s : string
96+
>42 : 42
97+
98+
mapped7({foo: s => 42});
99+
>mapped7({foo: s => 42}) : void
100+
>mapped7 : <K extends string | number | symbol>(obj: { [P in K]: TakeString; }) => void
101+
>{foo: s => 42} : { foo: (s: string) => number; }
102+
>foo : (s: string) => number
103+
>s => 42 : (s: string) => number
104+
>s : string
105+
>42 : 42
106+
107+
mapped8({foo: s => 42});
108+
>mapped8({foo: s => 42}) : void
109+
>mapped8 : <K extends "foo">(obj: { [P in K]: TakeString; }) => void
110+
>{foo: s => 42} : { foo: (s: string) => number; }
111+
>foo : (s: string) => number
112+
>s => 42 : (s: string) => number
113+
>s : string
114+
>42 : 42
115+
116+
mapped9({foo: s => 42});
117+
>mapped9({foo: s => 42}) : void
118+
>mapped9 : <K extends "foo" | "bar">(obj: { [P in K]: TakeString; }) => void
119+
>{foo: s => 42} : { foo: (s: string) => number; }
120+
>foo : (s: string) => number
121+
>s => 42 : (s: string) => number
122+
>s : string
123+
>42 : 42
124+

0 commit comments

Comments
 (0)