Skip to content

Commit 1b2ffa9

Browse files
TypeScript Botweswigham
authored andcommittedSep 6, 2019
Cherry-pick PR #33150 into release-3.6 (#33285)
Component commits: b86c86d Add heuristic for extracting irreducible `null` and `undefined` types from intersections of unions
1 parent acbcc0d commit 1b2ffa9

File tree

5 files changed

+677
-0
lines changed

5 files changed

+677
-0
lines changed
 

‎src/compiler/checker.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9980,6 +9980,16 @@ namespace ts {
99809980
return true;
99819981
}
99829982

9983+
function extractIrreducible(types: Type[], flag: TypeFlags) {
9984+
if (every(types, t => !!(t.flags & TypeFlags.Union) && some((t as UnionType).types, tt => !!(tt.flags & flag)))) {
9985+
for (let i = 0; i < types.length; i++) {
9986+
types[i] = filterType(types[i], t => !(t.flags & flag));
9987+
}
9988+
return true;
9989+
}
9990+
return false;
9991+
}
9992+
99839993
// If the given list of types contains more than one union of primitive types, replace the
99849994
// first with a union containing an intersection of those primitive types, then remove the
99859995
// other unions and return true. Otherwise, do nothing and return false.
@@ -10098,6 +10108,12 @@ namespace ts {
1009810108
// reduced we'll never reduce again, so this occurs at most once.
1009910109
result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
1010010110
}
10111+
else if (extractIrreducible(typeSet, TypeFlags.Undefined)) {
10112+
result = getUnionType([getIntersectionType(typeSet), undefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
10113+
}
10114+
else if (extractIrreducible(typeSet, TypeFlags.Null)) {
10115+
result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
10116+
}
1010110117
else {
1010210118
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
1010310119
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//// [partialOfLargeAPIIsAbleToBeWorkedWith.ts]
2+
interface MyAPI {
3+
0: (x: 0) => string;
4+
1: (x: 1) => string;
5+
2: (x: 2) => string;
6+
3: (x: 3) => string;
7+
4: (x: 4) => string;
8+
5: (x: 5) => string;
9+
6: (x: 6) => string;
10+
7: (x: 7) => string;
11+
8: (x: 8) => string;
12+
9: (x: 9) => string;
13+
10: (x: 10) => string;
14+
11: (x: 11) => string;
15+
12: (x: 12) => string;
16+
13: (x: 13) => string;
17+
14: (x: 14) => string;
18+
15: (x: 15) => string;
19+
16: (x: 16) => string;
20+
17: (x: 17) => string;
21+
18: (x: 18) => string;
22+
19: (x: 19) => string;
23+
20: (x: 20) => string;
24+
21: (x: 21) => string;
25+
22: (x: 22) => string;
26+
23: (x: 23) => string;
27+
24: (x: 24) => string;
28+
25: (x: 25) => string;
29+
26: (x: 26) => string;
30+
27: (x: 27) => string;
31+
28: (x: 28) => string;
32+
29: (x: 29) => string;
33+
30: (x: 30) => string;
34+
31: (x: 31) => string;
35+
32: (x: 32) => string;
36+
33: (x: 33) => string;
37+
34: (x: 34) => string;
38+
35: (x: 35) => string;
39+
36: (x: 36) => string;
40+
37: (x: 37) => string;
41+
38: (x: 38) => string;
42+
39: (x: 39) => string;
43+
40: (x: 40) => string;
44+
41: (x: 41) => string;
45+
42: (x: 42) => string;
46+
43: (x: 43) => string;
47+
44: (x: 44) => string;
48+
45: (x: 45) => string;
49+
46: (x: 46) => string;
50+
47: (x: 47) => string;
51+
48: (x: 48) => string;
52+
49: (x: 49) => string;
53+
50: (x: 50) => string;
54+
51: (x: 51) => string;
55+
}
56+
57+
const obj: Partial<MyAPI> = {};
58+
59+
declare var keys: (keyof MyAPI)[];
60+
61+
for (const k of keys) {
62+
obj[k] = () => "12"; // shouldn't cause a complexity error
63+
}
64+
65+
type PartialNull<T> = {[K in keyof T]?: T[K] | null};
66+
67+
const obj2: PartialNull<MyAPI> = {};
68+
69+
for (const k of keys) {
70+
obj2[k] = () => "12"; // shouldn't cause a complexity error
71+
}
72+
73+
74+
//// [partialOfLargeAPIIsAbleToBeWorkedWith.js]
75+
"use strict";
76+
var obj = {};
77+
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
78+
var k = keys_1[_i];
79+
obj[k] = function () { return "12"; }; // shouldn't cause a complexity error
80+
}
81+
var obj2 = {};
82+
for (var _a = 0, keys_2 = keys; _a < keys_2.length; _a++) {
83+
var k = keys_2[_a];
84+
obj2[k] = function () { return "12"; }; // shouldn't cause a complexity error
85+
}
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
=== tests/cases/compiler/partialOfLargeAPIIsAbleToBeWorkedWith.ts ===
2+
interface MyAPI {
3+
>MyAPI : Symbol(MyAPI, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 0, 0))
4+
5+
0: (x: 0) => string;
6+
>0 : Symbol(MyAPI[0], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 0, 17))
7+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 1, 8))
8+
9+
1: (x: 1) => string;
10+
>1 : Symbol(MyAPI[1], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 1, 24))
11+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 2, 8))
12+
13+
2: (x: 2) => string;
14+
>2 : Symbol(MyAPI[2], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 2, 24))
15+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 3, 8))
16+
17+
3: (x: 3) => string;
18+
>3 : Symbol(MyAPI[3], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 3, 24))
19+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 4, 8))
20+
21+
4: (x: 4) => string;
22+
>4 : Symbol(MyAPI[4], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 4, 24))
23+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 5, 8))
24+
25+
5: (x: 5) => string;
26+
>5 : Symbol(MyAPI[5], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 5, 24))
27+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 6, 8))
28+
29+
6: (x: 6) => string;
30+
>6 : Symbol(MyAPI[6], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 6, 24))
31+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 7, 8))
32+
33+
7: (x: 7) => string;
34+
>7 : Symbol(MyAPI[7], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 7, 24))
35+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 8, 8))
36+
37+
8: (x: 8) => string;
38+
>8 : Symbol(MyAPI[8], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 8, 24))
39+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 9, 8))
40+
41+
9: (x: 9) => string;
42+
>9 : Symbol(MyAPI[9], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 9, 24))
43+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 10, 8))
44+
45+
10: (x: 10) => string;
46+
>10 : Symbol(MyAPI[10], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 10, 24))
47+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 11, 9))
48+
49+
11: (x: 11) => string;
50+
>11 : Symbol(MyAPI[11], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 11, 26))
51+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 12, 9))
52+
53+
12: (x: 12) => string;
54+
>12 : Symbol(MyAPI[12], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 12, 26))
55+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 13, 9))
56+
57+
13: (x: 13) => string;
58+
>13 : Symbol(MyAPI[13], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 13, 26))
59+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 14, 9))
60+
61+
14: (x: 14) => string;
62+
>14 : Symbol(MyAPI[14], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 14, 26))
63+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 15, 9))
64+
65+
15: (x: 15) => string;
66+
>15 : Symbol(MyAPI[15], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 15, 26))
67+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 16, 9))
68+
69+
16: (x: 16) => string;
70+
>16 : Symbol(MyAPI[16], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 16, 26))
71+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 17, 9))
72+
73+
17: (x: 17) => string;
74+
>17 : Symbol(MyAPI[17], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 17, 26))
75+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 18, 9))
76+
77+
18: (x: 18) => string;
78+
>18 : Symbol(MyAPI[18], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 18, 26))
79+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 19, 9))
80+
81+
19: (x: 19) => string;
82+
>19 : Symbol(MyAPI[19], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 19, 26))
83+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 20, 9))
84+
85+
20: (x: 20) => string;
86+
>20 : Symbol(MyAPI[20], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 20, 26))
87+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 21, 9))
88+
89+
21: (x: 21) => string;
90+
>21 : Symbol(MyAPI[21], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 21, 26))
91+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 22, 9))
92+
93+
22: (x: 22) => string;
94+
>22 : Symbol(MyAPI[22], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 22, 26))
95+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 23, 9))
96+
97+
23: (x: 23) => string;
98+
>23 : Symbol(MyAPI[23], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 23, 26))
99+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 24, 9))
100+
101+
24: (x: 24) => string;
102+
>24 : Symbol(MyAPI[24], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 24, 26))
103+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 25, 9))
104+
105+
25: (x: 25) => string;
106+
>25 : Symbol(MyAPI[25], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 25, 26))
107+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 26, 9))
108+
109+
26: (x: 26) => string;
110+
>26 : Symbol(MyAPI[26], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 26, 26))
111+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 27, 9))
112+
113+
27: (x: 27) => string;
114+
>27 : Symbol(MyAPI[27], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 27, 26))
115+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 28, 9))
116+
117+
28: (x: 28) => string;
118+
>28 : Symbol(MyAPI[28], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 28, 26))
119+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 29, 9))
120+
121+
29: (x: 29) => string;
122+
>29 : Symbol(MyAPI[29], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 29, 26))
123+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 30, 9))
124+
125+
30: (x: 30) => string;
126+
>30 : Symbol(MyAPI[30], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 30, 26))
127+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 31, 9))
128+
129+
31: (x: 31) => string;
130+
>31 : Symbol(MyAPI[31], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 31, 26))
131+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 32, 9))
132+
133+
32: (x: 32) => string;
134+
>32 : Symbol(MyAPI[32], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 32, 26))
135+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 33, 9))
136+
137+
33: (x: 33) => string;
138+
>33 : Symbol(MyAPI[33], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 33, 26))
139+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 34, 9))
140+
141+
34: (x: 34) => string;
142+
>34 : Symbol(MyAPI[34], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 34, 26))
143+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 35, 9))
144+
145+
35: (x: 35) => string;
146+
>35 : Symbol(MyAPI[35], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 35, 26))
147+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 36, 9))
148+
149+
36: (x: 36) => string;
150+
>36 : Symbol(MyAPI[36], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 36, 26))
151+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 37, 9))
152+
153+
37: (x: 37) => string;
154+
>37 : Symbol(MyAPI[37], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 37, 26))
155+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 38, 9))
156+
157+
38: (x: 38) => string;
158+
>38 : Symbol(MyAPI[38], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 38, 26))
159+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 39, 9))
160+
161+
39: (x: 39) => string;
162+
>39 : Symbol(MyAPI[39], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 39, 26))
163+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 40, 9))
164+
165+
40: (x: 40) => string;
166+
>40 : Symbol(MyAPI[40], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 40, 26))
167+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 41, 9))
168+
169+
41: (x: 41) => string;
170+
>41 : Symbol(MyAPI[41], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 41, 26))
171+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 42, 9))
172+
173+
42: (x: 42) => string;
174+
>42 : Symbol(MyAPI[42], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 42, 26))
175+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 43, 9))
176+
177+
43: (x: 43) => string;
178+
>43 : Symbol(MyAPI[43], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 43, 26))
179+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 44, 9))
180+
181+
44: (x: 44) => string;
182+
>44 : Symbol(MyAPI[44], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 44, 26))
183+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 45, 9))
184+
185+
45: (x: 45) => string;
186+
>45 : Symbol(MyAPI[45], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 45, 26))
187+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 46, 9))
188+
189+
46: (x: 46) => string;
190+
>46 : Symbol(MyAPI[46], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 46, 26))
191+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 47, 9))
192+
193+
47: (x: 47) => string;
194+
>47 : Symbol(MyAPI[47], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 47, 26))
195+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 48, 9))
196+
197+
48: (x: 48) => string;
198+
>48 : Symbol(MyAPI[48], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 48, 26))
199+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 49, 9))
200+
201+
49: (x: 49) => string;
202+
>49 : Symbol(MyAPI[49], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 49, 26))
203+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 50, 9))
204+
205+
50: (x: 50) => string;
206+
>50 : Symbol(MyAPI[50], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 50, 26))
207+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 51, 9))
208+
209+
51: (x: 51) => string;
210+
>51 : Symbol(MyAPI[51], Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 51, 26))
211+
>x : Symbol(x, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 52, 9))
212+
}
213+
214+
const obj: Partial<MyAPI> = {};
215+
>obj : Symbol(obj, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 55, 5))
216+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
217+
>MyAPI : Symbol(MyAPI, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 0, 0))
218+
219+
declare var keys: (keyof MyAPI)[];
220+
>keys : Symbol(keys, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 57, 11))
221+
>MyAPI : Symbol(MyAPI, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 0, 0))
222+
223+
for (const k of keys) {
224+
>k : Symbol(k, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 59, 10))
225+
>keys : Symbol(keys, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 57, 11))
226+
227+
obj[k] = () => "12"; // shouldn't cause a complexity error
228+
>obj : Symbol(obj, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 55, 5))
229+
>k : Symbol(k, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 59, 10))
230+
}
231+
232+
type PartialNull<T> = {[K in keyof T]?: T[K] | null};
233+
>PartialNull : Symbol(PartialNull, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 61, 1))
234+
>T : Symbol(T, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 63, 17))
235+
>K : Symbol(K, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 63, 24))
236+
>T : Symbol(T, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 63, 17))
237+
>T : Symbol(T, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 63, 17))
238+
>K : Symbol(K, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 63, 24))
239+
240+
const obj2: PartialNull<MyAPI> = {};
241+
>obj2 : Symbol(obj2, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 65, 5))
242+
>PartialNull : Symbol(PartialNull, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 61, 1))
243+
>MyAPI : Symbol(MyAPI, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 0, 0))
244+
245+
for (const k of keys) {
246+
>k : Symbol(k, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 67, 10))
247+
>keys : Symbol(keys, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 57, 11))
248+
249+
obj2[k] = () => "12"; // shouldn't cause a complexity error
250+
>obj2 : Symbol(obj2, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 65, 5))
251+
>k : Symbol(k, Decl(partialOfLargeAPIIsAbleToBeWorkedWith.ts, 67, 10))
252+
}
253+
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
=== tests/cases/compiler/partialOfLargeAPIIsAbleToBeWorkedWith.ts ===
2+
interface MyAPI {
3+
0: (x: 0) => string;
4+
>0 : (x: 0) => string
5+
>x : 0
6+
7+
1: (x: 1) => string;
8+
>1 : (x: 1) => string
9+
>x : 1
10+
11+
2: (x: 2) => string;
12+
>2 : (x: 2) => string
13+
>x : 2
14+
15+
3: (x: 3) => string;
16+
>3 : (x: 3) => string
17+
>x : 3
18+
19+
4: (x: 4) => string;
20+
>4 : (x: 4) => string
21+
>x : 4
22+
23+
5: (x: 5) => string;
24+
>5 : (x: 5) => string
25+
>x : 5
26+
27+
6: (x: 6) => string;
28+
>6 : (x: 6) => string
29+
>x : 6
30+
31+
7: (x: 7) => string;
32+
>7 : (x: 7) => string
33+
>x : 7
34+
35+
8: (x: 8) => string;
36+
>8 : (x: 8) => string
37+
>x : 8
38+
39+
9: (x: 9) => string;
40+
>9 : (x: 9) => string
41+
>x : 9
42+
43+
10: (x: 10) => string;
44+
>10 : (x: 10) => string
45+
>x : 10
46+
47+
11: (x: 11) => string;
48+
>11 : (x: 11) => string
49+
>x : 11
50+
51+
12: (x: 12) => string;
52+
>12 : (x: 12) => string
53+
>x : 12
54+
55+
13: (x: 13) => string;
56+
>13 : (x: 13) => string
57+
>x : 13
58+
59+
14: (x: 14) => string;
60+
>14 : (x: 14) => string
61+
>x : 14
62+
63+
15: (x: 15) => string;
64+
>15 : (x: 15) => string
65+
>x : 15
66+
67+
16: (x: 16) => string;
68+
>16 : (x: 16) => string
69+
>x : 16
70+
71+
17: (x: 17) => string;
72+
>17 : (x: 17) => string
73+
>x : 17
74+
75+
18: (x: 18) => string;
76+
>18 : (x: 18) => string
77+
>x : 18
78+
79+
19: (x: 19) => string;
80+
>19 : (x: 19) => string
81+
>x : 19
82+
83+
20: (x: 20) => string;
84+
>20 : (x: 20) => string
85+
>x : 20
86+
87+
21: (x: 21) => string;
88+
>21 : (x: 21) => string
89+
>x : 21
90+
91+
22: (x: 22) => string;
92+
>22 : (x: 22) => string
93+
>x : 22
94+
95+
23: (x: 23) => string;
96+
>23 : (x: 23) => string
97+
>x : 23
98+
99+
24: (x: 24) => string;
100+
>24 : (x: 24) => string
101+
>x : 24
102+
103+
25: (x: 25) => string;
104+
>25 : (x: 25) => string
105+
>x : 25
106+
107+
26: (x: 26) => string;
108+
>26 : (x: 26) => string
109+
>x : 26
110+
111+
27: (x: 27) => string;
112+
>27 : (x: 27) => string
113+
>x : 27
114+
115+
28: (x: 28) => string;
116+
>28 : (x: 28) => string
117+
>x : 28
118+
119+
29: (x: 29) => string;
120+
>29 : (x: 29) => string
121+
>x : 29
122+
123+
30: (x: 30) => string;
124+
>30 : (x: 30) => string
125+
>x : 30
126+
127+
31: (x: 31) => string;
128+
>31 : (x: 31) => string
129+
>x : 31
130+
131+
32: (x: 32) => string;
132+
>32 : (x: 32) => string
133+
>x : 32
134+
135+
33: (x: 33) => string;
136+
>33 : (x: 33) => string
137+
>x : 33
138+
139+
34: (x: 34) => string;
140+
>34 : (x: 34) => string
141+
>x : 34
142+
143+
35: (x: 35) => string;
144+
>35 : (x: 35) => string
145+
>x : 35
146+
147+
36: (x: 36) => string;
148+
>36 : (x: 36) => string
149+
>x : 36
150+
151+
37: (x: 37) => string;
152+
>37 : (x: 37) => string
153+
>x : 37
154+
155+
38: (x: 38) => string;
156+
>38 : (x: 38) => string
157+
>x : 38
158+
159+
39: (x: 39) => string;
160+
>39 : (x: 39) => string
161+
>x : 39
162+
163+
40: (x: 40) => string;
164+
>40 : (x: 40) => string
165+
>x : 40
166+
167+
41: (x: 41) => string;
168+
>41 : (x: 41) => string
169+
>x : 41
170+
171+
42: (x: 42) => string;
172+
>42 : (x: 42) => string
173+
>x : 42
174+
175+
43: (x: 43) => string;
176+
>43 : (x: 43) => string
177+
>x : 43
178+
179+
44: (x: 44) => string;
180+
>44 : (x: 44) => string
181+
>x : 44
182+
183+
45: (x: 45) => string;
184+
>45 : (x: 45) => string
185+
>x : 45
186+
187+
46: (x: 46) => string;
188+
>46 : (x: 46) => string
189+
>x : 46
190+
191+
47: (x: 47) => string;
192+
>47 : (x: 47) => string
193+
>x : 47
194+
195+
48: (x: 48) => string;
196+
>48 : (x: 48) => string
197+
>x : 48
198+
199+
49: (x: 49) => string;
200+
>49 : (x: 49) => string
201+
>x : 49
202+
203+
50: (x: 50) => string;
204+
>50 : (x: 50) => string
205+
>x : 50
206+
207+
51: (x: 51) => string;
208+
>51 : (x: 51) => string
209+
>x : 51
210+
}
211+
212+
const obj: Partial<MyAPI> = {};
213+
>obj : Partial<MyAPI>
214+
>{} : {}
215+
216+
declare var keys: (keyof MyAPI)[];
217+
>keys : (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51)[]
218+
219+
for (const k of keys) {
220+
>k : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51
221+
>keys : (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51)[]
222+
223+
obj[k] = () => "12"; // shouldn't cause a complexity error
224+
>obj[k] = () => "12" : () => string
225+
>obj[k] : (((x: 0) => string) & ((x: 1) => string) & ((x: 2) => string) & ((x: 3) => string) & ((x: 4) => string) & ((x: 5) => string) & ((x: 6) => string) & ((x: 7) => string) & ((x: 8) => string) & ((x: 9) => string) & ((x: 10) => string) & ((x: 11) => string) & ((x: 12) => string) & ((x: 13) => string) & ((x: 14) => string) & ((x: 15) => string) & ((x: 16) => string) & ((x: 17) => string) & ((x: 18) => string) & ((x: 19) => string) & ((x: 20) => string) & ((x: 21) => string) & ((x: 22) => string) & ((x: 23) => string) & ((x: 24) => string) & ((x: 25) => string) & ((x: 26) => string) & ((x: 27) => string) & ((x: 28) => string) & ((x: 29) => string) & ((x: 30) => string) & ((x: 31) => string) & ((x: 32) => string) & ((x: 33) => string) & ((x: 34) => string) & ((x: 35) => string) & ((x: 36) => string) & ((x: 37) => string) & ((x: 38) => string) & ((x: 39) => string) & ((x: 40) => string) & ((x: 41) => string) & ((x: 42) => string) & ((x: 43) => string) & ((x: 44) => string) & ((x: 45) => string) & ((x: 46) => string) & ((x: 47) => string) & ((x: 48) => string) & ((x: 49) => string) & ((x: 50) => string) & ((x: 51) => string)) | undefined
226+
>obj : Partial<MyAPI>
227+
>k : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51
228+
>() => "12" : () => string
229+
>"12" : "12"
230+
}
231+
232+
type PartialNull<T> = {[K in keyof T]?: T[K] | null};
233+
>PartialNull : PartialNull<T>
234+
>null : null
235+
236+
const obj2: PartialNull<MyAPI> = {};
237+
>obj2 : PartialNull<MyAPI>
238+
>{} : {}
239+
240+
for (const k of keys) {
241+
>k : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51
242+
>keys : (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51)[]
243+
244+
obj2[k] = () => "12"; // shouldn't cause a complexity error
245+
>obj2[k] = () => "12" : () => string
246+
>obj2[k] : (((x: 0) => string) & ((x: 1) => string) & ((x: 2) => string) & ((x: 3) => string) & ((x: 4) => string) & ((x: 5) => string) & ((x: 6) => string) & ((x: 7) => string) & ((x: 8) => string) & ((x: 9) => string) & ((x: 10) => string) & ((x: 11) => string) & ((x: 12) => string) & ((x: 13) => string) & ((x: 14) => string) & ((x: 15) => string) & ((x: 16) => string) & ((x: 17) => string) & ((x: 18) => string) & ((x: 19) => string) & ((x: 20) => string) & ((x: 21) => string) & ((x: 22) => string) & ((x: 23) => string) & ((x: 24) => string) & ((x: 25) => string) & ((x: 26) => string) & ((x: 27) => string) & ((x: 28) => string) & ((x: 29) => string) & ((x: 30) => string) & ((x: 31) => string) & ((x: 32) => string) & ((x: 33) => string) & ((x: 34) => string) & ((x: 35) => string) & ((x: 36) => string) & ((x: 37) => string) & ((x: 38) => string) & ((x: 39) => string) & ((x: 40) => string) & ((x: 41) => string) & ((x: 42) => string) & ((x: 43) => string) & ((x: 44) => string) & ((x: 45) => string) & ((x: 46) => string) & ((x: 47) => string) & ((x: 48) => string) & ((x: 49) => string) & ((x: 50) => string) & ((x: 51) => string)) | null | undefined
247+
>obj2 : PartialNull<MyAPI>
248+
>k : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51
249+
>() => "12" : () => string
250+
>"12" : "12"
251+
}
252+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// @strict: true
2+
interface MyAPI {
3+
0: (x: 0) => string;
4+
1: (x: 1) => string;
5+
2: (x: 2) => string;
6+
3: (x: 3) => string;
7+
4: (x: 4) => string;
8+
5: (x: 5) => string;
9+
6: (x: 6) => string;
10+
7: (x: 7) => string;
11+
8: (x: 8) => string;
12+
9: (x: 9) => string;
13+
10: (x: 10) => string;
14+
11: (x: 11) => string;
15+
12: (x: 12) => string;
16+
13: (x: 13) => string;
17+
14: (x: 14) => string;
18+
15: (x: 15) => string;
19+
16: (x: 16) => string;
20+
17: (x: 17) => string;
21+
18: (x: 18) => string;
22+
19: (x: 19) => string;
23+
20: (x: 20) => string;
24+
21: (x: 21) => string;
25+
22: (x: 22) => string;
26+
23: (x: 23) => string;
27+
24: (x: 24) => string;
28+
25: (x: 25) => string;
29+
26: (x: 26) => string;
30+
27: (x: 27) => string;
31+
28: (x: 28) => string;
32+
29: (x: 29) => string;
33+
30: (x: 30) => string;
34+
31: (x: 31) => string;
35+
32: (x: 32) => string;
36+
33: (x: 33) => string;
37+
34: (x: 34) => string;
38+
35: (x: 35) => string;
39+
36: (x: 36) => string;
40+
37: (x: 37) => string;
41+
38: (x: 38) => string;
42+
39: (x: 39) => string;
43+
40: (x: 40) => string;
44+
41: (x: 41) => string;
45+
42: (x: 42) => string;
46+
43: (x: 43) => string;
47+
44: (x: 44) => string;
48+
45: (x: 45) => string;
49+
46: (x: 46) => string;
50+
47: (x: 47) => string;
51+
48: (x: 48) => string;
52+
49: (x: 49) => string;
53+
50: (x: 50) => string;
54+
51: (x: 51) => string;
55+
}
56+
57+
const obj: Partial<MyAPI> = {};
58+
59+
declare var keys: (keyof MyAPI)[];
60+
61+
for (const k of keys) {
62+
obj[k] = () => "12"; // shouldn't cause a complexity error
63+
}
64+
65+
type PartialNull<T> = {[K in keyof T]?: T[K] | null};
66+
67+
const obj2: PartialNull<MyAPI> = {};
68+
69+
for (const k of keys) {
70+
obj2[k] = () => "12"; // shouldn't cause a complexity error
71+
}

0 commit comments

Comments
 (0)
Please sign in to comment.