Skip to content

Commit 3b1b82a

Browse files
authored
Add optionality to mapped type indexed access substitutions (#57549)
1 parent 8336042 commit 3b1b82a

5 files changed

+567
-4
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14026,15 +14026,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1402614026
(declaration.questionToken ? declaration.questionToken.kind === SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeOptional : MappedTypeModifiers.IncludeOptional : 0);
1402714027
}
1402814028

14029+
// Return -1, 0, or 1, where -1 means optionality is stripped (i.e. -?), 0 means optionality is unchanged, and 1 means
14030+
// optionality is added (i.e. +?).
1402914031
function getMappedTypeOptionality(type: MappedType): number {
1403014032
const modifiers = getMappedTypeModifiers(type);
1403114033
return modifiers & MappedTypeModifiers.ExcludeOptional ? -1 : modifiers & MappedTypeModifiers.IncludeOptional ? 1 : 0;
1403214034
}
1403314035

14036+
function getModifiersTypeOptionality(type: Type): number {
14037+
return type.flags & TypeFlags.Intersection ? Math.max(...map((type as IntersectionType).types, getModifiersTypeOptionality)) :
14038+
getObjectFlags(type) & ObjectFlags.Mapped ? getCombinedMappedTypeOptionality(type as MappedType) :
14039+
0;
14040+
}
14041+
14042+
// Return -1, 0, or 1, for stripped, unchanged, or added optionality respectively. When a homomorphic mapped type doesn't
14043+
// modify optionality, recursively consult the optionality of the type being mapped over to see if it strips or adds optionality.
1403414044
function getCombinedMappedTypeOptionality(type: MappedType): number {
14035-
const optionality = getMappedTypeOptionality(type);
14036-
const modifiersType = getModifiersTypeFromMappedType(type);
14037-
return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0);
14045+
return getMappedTypeOptionality(type) || getModifiersTypeOptionality(getModifiersTypeFromMappedType(type));
1403814046
}
1403914047

1404014048
function isPartialMappedType(type: Type) {
@@ -18505,7 +18513,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1850518513
function substituteIndexedMappedType(objectType: MappedType, index: Type) {
1850618514
const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
1850718515
const templateMapper = combineTypeMappers(objectType.mapper, mapper);
18508-
return instantiateType(getTemplateTypeFromMappedType(objectType.target as MappedType || objectType), templateMapper);
18516+
const instantiatedTemplateType = instantiateType(getTemplateTypeFromMappedType(objectType.target as MappedType || objectType), templateMapper);
18517+
return addOptionality(instantiatedTemplateType, /*isProperty*/ true, getCombinedMappedTypeOptionality(objectType) > 0);
1850918518
}
1851018519

1851118520
function getIndexedAccessType(objectType: Type, indexType: Type, accessFlags = AccessFlags.None, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
mappedTypeIndexedAccessConstraint.ts(12,5): error TS18048: 'm1' is possibly 'undefined'.
2+
mappedTypeIndexedAccessConstraint.ts(14,5): error TS18048: 'm2' is possibly 'undefined'.
3+
mappedTypeIndexedAccessConstraint.ts(16,5): error TS18048: 'm3' is possibly 'undefined'.
4+
mappedTypeIndexedAccessConstraint.ts(29,66): error TS2532: Object is possibly 'undefined'.
5+
mappedTypeIndexedAccessConstraint.ts(53,34): error TS2722: Cannot invoke an object which is possibly 'undefined'.
6+
7+
8+
==== mappedTypeIndexedAccessConstraint.ts (5 errors) ====
9+
type Identity<T> = { [K in keyof T]: T[K] };
10+
11+
type M0 = { a: 1, b: 2 };
12+
13+
type M1 = { [K in keyof Partial<M0>]: M0[K] };
14+
15+
type M2 = { [K in keyof Required<M1>]: M1[K] };
16+
17+
type M3 = { [K in keyof Identity<Partial<M0>>]: M0[K] };
18+
19+
function foo<K extends keyof M0>(m1: M1[K], m2: M2[K], m3: M3[K]) {
20+
m1.toString(); // Error
21+
~~
22+
!!! error TS18048: 'm1' is possibly 'undefined'.
23+
m1?.toString();
24+
m2.toString(); // Error
25+
~~
26+
!!! error TS18048: 'm2' is possibly 'undefined'.
27+
m2?.toString();
28+
m3.toString(); // Error
29+
~~
30+
!!! error TS18048: 'm3' is possibly 'undefined'.
31+
m3?.toString();
32+
}
33+
34+
// Repro from #57487
35+
36+
type Obj = {
37+
a: 1,
38+
b: 2
39+
};
40+
41+
const mapped: { [K in keyof Partial<Obj>]: Obj[K] } = {};
42+
43+
const resolveMapped = <K extends keyof typeof mapped>(key: K) => mapped[key].toString(); // Error
44+
~~~~~~~~~~~
45+
!!! error TS2532: Object is possibly 'undefined'.
46+
47+
// Additional repro from #57487
48+
49+
const arr = ["foo", "12", 42] as const;
50+
51+
type Mappings = { foo: boolean, "12": number, 42: string };
52+
53+
type MapperArgs<K extends (typeof arr)[number]> = {
54+
v: K,
55+
i: number
56+
};
57+
58+
type SetOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
59+
60+
type PartMappings = SetOptional<Mappings, "foo">;
61+
62+
const mapper: { [K in keyof PartMappings]: (o: MapperArgs<K>) => PartMappings[K] } = {
63+
foo: ({ v, i }) => v.length + i > 4,
64+
"12": ({ v, i }) => Number(v) + i,
65+
42: ({ v, i }) => `${v}${i}`,
66+
}
67+
68+
const resolveMapper1 = <K extends keyof typeof mapper>(
69+
key: K, o: MapperArgs<K>) => mapper[key](o); // Error
70+
~~~~~~~~~~~
71+
!!! error TS2722: Cannot invoke an object which is possibly 'undefined'.
72+
73+
const resolveMapper2 = <K extends keyof typeof mapper>(
74+
key: K, o: MapperArgs<K>) => mapper[key]?.(o)
75+
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
//// [tests/cases/compiler/mappedTypeIndexedAccessConstraint.ts] ////
2+
3+
=== mappedTypeIndexedAccessConstraint.ts ===
4+
type Identity<T> = { [K in keyof T]: T[K] };
5+
>Identity : Symbol(Identity, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 0))
6+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 14))
7+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 22))
8+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 14))
9+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 14))
10+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 22))
11+
12+
type M0 = { a: 1, b: 2 };
13+
>M0 : Symbol(M0, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 44))
14+
>a : Symbol(a, Decl(mappedTypeIndexedAccessConstraint.ts, 2, 11))
15+
>b : Symbol(b, Decl(mappedTypeIndexedAccessConstraint.ts, 2, 17))
16+
17+
type M1 = { [K in keyof Partial<M0>]: M0[K] };
18+
>M1 : Symbol(M1, Decl(mappedTypeIndexedAccessConstraint.ts, 2, 25))
19+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 4, 13))
20+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
21+
>M0 : Symbol(M0, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 44))
22+
>M0 : Symbol(M0, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 44))
23+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 4, 13))
24+
25+
type M2 = { [K in keyof Required<M1>]: M1[K] };
26+
>M2 : Symbol(M2, Decl(mappedTypeIndexedAccessConstraint.ts, 4, 46))
27+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 6, 13))
28+
>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --))
29+
>M1 : Symbol(M1, Decl(mappedTypeIndexedAccessConstraint.ts, 2, 25))
30+
>M1 : Symbol(M1, Decl(mappedTypeIndexedAccessConstraint.ts, 2, 25))
31+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 6, 13))
32+
33+
type M3 = { [K in keyof Identity<Partial<M0>>]: M0[K] };
34+
>M3 : Symbol(M3, Decl(mappedTypeIndexedAccessConstraint.ts, 6, 47))
35+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 8, 13))
36+
>Identity : Symbol(Identity, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 0))
37+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
38+
>M0 : Symbol(M0, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 44))
39+
>M0 : Symbol(M0, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 44))
40+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 8, 13))
41+
42+
function foo<K extends keyof M0>(m1: M1[K], m2: M2[K], m3: M3[K]) {
43+
>foo : Symbol(foo, Decl(mappedTypeIndexedAccessConstraint.ts, 8, 56))
44+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 13))
45+
>M0 : Symbol(M0, Decl(mappedTypeIndexedAccessConstraint.ts, 0, 44))
46+
>m1 : Symbol(m1, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 33))
47+
>M1 : Symbol(M1, Decl(mappedTypeIndexedAccessConstraint.ts, 2, 25))
48+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 13))
49+
>m2 : Symbol(m2, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 43))
50+
>M2 : Symbol(M2, Decl(mappedTypeIndexedAccessConstraint.ts, 4, 46))
51+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 13))
52+
>m3 : Symbol(m3, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 54))
53+
>M3 : Symbol(M3, Decl(mappedTypeIndexedAccessConstraint.ts, 6, 47))
54+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 13))
55+
56+
m1.toString(); // Error
57+
>m1.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
58+
>m1 : Symbol(m1, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 33))
59+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
60+
61+
m1?.toString();
62+
>m1?.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
63+
>m1 : Symbol(m1, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 33))
64+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
65+
66+
m2.toString(); // Error
67+
>m2.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
68+
>m2 : Symbol(m2, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 43))
69+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
70+
71+
m2?.toString();
72+
>m2?.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
73+
>m2 : Symbol(m2, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 43))
74+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
75+
76+
m3.toString(); // Error
77+
>m3.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
78+
>m3 : Symbol(m3, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 54))
79+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
80+
81+
m3?.toString();
82+
>m3?.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
83+
>m3 : Symbol(m3, Decl(mappedTypeIndexedAccessConstraint.ts, 10, 54))
84+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
85+
}
86+
87+
// Repro from #57487
88+
89+
type Obj = {
90+
>Obj : Symbol(Obj, Decl(mappedTypeIndexedAccessConstraint.ts, 17, 1))
91+
92+
a: 1,
93+
>a : Symbol(a, Decl(mappedTypeIndexedAccessConstraint.ts, 21, 12))
94+
95+
b: 2
96+
>b : Symbol(b, Decl(mappedTypeIndexedAccessConstraint.ts, 22, 9))
97+
98+
};
99+
100+
const mapped: { [K in keyof Partial<Obj>]: Obj[K] } = {};
101+
>mapped : Symbol(mapped, Decl(mappedTypeIndexedAccessConstraint.ts, 26, 5))
102+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 26, 17))
103+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
104+
>Obj : Symbol(Obj, Decl(mappedTypeIndexedAccessConstraint.ts, 17, 1))
105+
>Obj : Symbol(Obj, Decl(mappedTypeIndexedAccessConstraint.ts, 17, 1))
106+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 26, 17))
107+
108+
const resolveMapped = <K extends keyof typeof mapped>(key: K) => mapped[key].toString(); // Error
109+
>resolveMapped : Symbol(resolveMapped, Decl(mappedTypeIndexedAccessConstraint.ts, 28, 5))
110+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 28, 23))
111+
>mapped : Symbol(mapped, Decl(mappedTypeIndexedAccessConstraint.ts, 26, 5))
112+
>key : Symbol(key, Decl(mappedTypeIndexedAccessConstraint.ts, 28, 54))
113+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 28, 23))
114+
>mapped[key].toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
115+
>mapped : Symbol(mapped, Decl(mappedTypeIndexedAccessConstraint.ts, 26, 5))
116+
>key : Symbol(key, Decl(mappedTypeIndexedAccessConstraint.ts, 28, 54))
117+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
118+
119+
// Additional repro from #57487
120+
121+
const arr = ["foo", "12", 42] as const;
122+
>arr : Symbol(arr, Decl(mappedTypeIndexedAccessConstraint.ts, 32, 5))
123+
>const : Symbol(const)
124+
125+
type Mappings = { foo: boolean, "12": number, 42: string };
126+
>Mappings : Symbol(Mappings, Decl(mappedTypeIndexedAccessConstraint.ts, 32, 39))
127+
>foo : Symbol(foo, Decl(mappedTypeIndexedAccessConstraint.ts, 34, 17))
128+
>"12" : Symbol("12", Decl(mappedTypeIndexedAccessConstraint.ts, 34, 31))
129+
>42 : Symbol(42, Decl(mappedTypeIndexedAccessConstraint.ts, 34, 45))
130+
131+
type MapperArgs<K extends (typeof arr)[number]> = {
132+
>MapperArgs : Symbol(MapperArgs, Decl(mappedTypeIndexedAccessConstraint.ts, 34, 59))
133+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 36, 16))
134+
>arr : Symbol(arr, Decl(mappedTypeIndexedAccessConstraint.ts, 32, 5))
135+
136+
v: K,
137+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 36, 51))
138+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 36, 16))
139+
140+
i: number
141+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 37, 9))
142+
143+
};
144+
145+
type SetOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
146+
>SetOptional : Symbol(SetOptional, Decl(mappedTypeIndexedAccessConstraint.ts, 39, 2))
147+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 17))
148+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 19))
149+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 17))
150+
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
151+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 17))
152+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 19))
153+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
154+
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
155+
>T : Symbol(T, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 17))
156+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 19))
157+
158+
type PartMappings = SetOptional<Mappings, "foo">;
159+
>PartMappings : Symbol(PartMappings, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 74))
160+
>SetOptional : Symbol(SetOptional, Decl(mappedTypeIndexedAccessConstraint.ts, 39, 2))
161+
>Mappings : Symbol(Mappings, Decl(mappedTypeIndexedAccessConstraint.ts, 32, 39))
162+
163+
const mapper: { [K in keyof PartMappings]: (o: MapperArgs<K>) => PartMappings[K] } = {
164+
>mapper : Symbol(mapper, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 5))
165+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 17))
166+
>PartMappings : Symbol(PartMappings, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 74))
167+
>o : Symbol(o, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 44))
168+
>MapperArgs : Symbol(MapperArgs, Decl(mappedTypeIndexedAccessConstraint.ts, 34, 59))
169+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 17))
170+
>PartMappings : Symbol(PartMappings, Decl(mappedTypeIndexedAccessConstraint.ts, 41, 74))
171+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 17))
172+
173+
foo: ({ v, i }) => v.length + i > 4,
174+
>foo : Symbol(foo, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 86))
175+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 46, 11))
176+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 46, 14))
177+
>v.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
178+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 46, 11))
179+
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
180+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 46, 14))
181+
182+
"12": ({ v, i }) => Number(v) + i,
183+
>"12" : Symbol("12", Decl(mappedTypeIndexedAccessConstraint.ts, 46, 40))
184+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 47, 12))
185+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 47, 15))
186+
>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
187+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 47, 12))
188+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 47, 15))
189+
190+
42: ({ v, i }) => `${v}${i}`,
191+
>42 : Symbol(42, Decl(mappedTypeIndexedAccessConstraint.ts, 47, 38))
192+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 48, 10))
193+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 48, 13))
194+
>v : Symbol(v, Decl(mappedTypeIndexedAccessConstraint.ts, 48, 10))
195+
>i : Symbol(i, Decl(mappedTypeIndexedAccessConstraint.ts, 48, 13))
196+
}
197+
198+
const resolveMapper1 = <K extends keyof typeof mapper>(
199+
>resolveMapper1 : Symbol(resolveMapper1, Decl(mappedTypeIndexedAccessConstraint.ts, 51, 5))
200+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 51, 24))
201+
>mapper : Symbol(mapper, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 5))
202+
203+
key: K, o: MapperArgs<K>) => mapper[key](o); // Error
204+
>key : Symbol(key, Decl(mappedTypeIndexedAccessConstraint.ts, 51, 55))
205+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 51, 24))
206+
>o : Symbol(o, Decl(mappedTypeIndexedAccessConstraint.ts, 52, 11))
207+
>MapperArgs : Symbol(MapperArgs, Decl(mappedTypeIndexedAccessConstraint.ts, 34, 59))
208+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 51, 24))
209+
>mapper : Symbol(mapper, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 5))
210+
>key : Symbol(key, Decl(mappedTypeIndexedAccessConstraint.ts, 51, 55))
211+
>o : Symbol(o, Decl(mappedTypeIndexedAccessConstraint.ts, 52, 11))
212+
213+
const resolveMapper2 = <K extends keyof typeof mapper>(
214+
>resolveMapper2 : Symbol(resolveMapper2, Decl(mappedTypeIndexedAccessConstraint.ts, 54, 5))
215+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 54, 24))
216+
>mapper : Symbol(mapper, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 5))
217+
218+
key: K, o: MapperArgs<K>) => mapper[key]?.(o)
219+
>key : Symbol(key, Decl(mappedTypeIndexedAccessConstraint.ts, 54, 55))
220+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 54, 24))
221+
>o : Symbol(o, Decl(mappedTypeIndexedAccessConstraint.ts, 55, 11))
222+
>MapperArgs : Symbol(MapperArgs, Decl(mappedTypeIndexedAccessConstraint.ts, 34, 59))
223+
>K : Symbol(K, Decl(mappedTypeIndexedAccessConstraint.ts, 54, 24))
224+
>mapper : Symbol(mapper, Decl(mappedTypeIndexedAccessConstraint.ts, 45, 5))
225+
>key : Symbol(key, Decl(mappedTypeIndexedAccessConstraint.ts, 54, 55))
226+
>o : Symbol(o, Decl(mappedTypeIndexedAccessConstraint.ts, 55, 11))
227+

0 commit comments

Comments
 (0)