Skip to content

Commit f5f2923

Browse files
authoredSep 12, 2022
Revert removal of nonInferrableAnyType (#50691)
1 parent 7120b52 commit f5f2923

5 files changed

+234
-2
lines changed
 

‎src/compiler/checker.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ namespace ts {
791791
const wildcardType = createIntrinsicType(TypeFlags.Any, "any");
792792
const errorType = createIntrinsicType(TypeFlags.Any, "error");
793793
const unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved");
794+
const nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType);
794795
const intrinsicMarkerType = createIntrinsicType(TypeFlags.Any, "intrinsic");
795796
const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
796797
const nonNullUnknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
@@ -9560,7 +9561,11 @@ namespace ts {
95609561
if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) {
95619562
reportImplicitAny(element, anyType);
95629563
}
9563-
return anyType;
9564+
// When we're including the pattern in the type (an indication we're obtaining a contextual type), we
9565+
// use a non-inferrable any type. Inference will never directly infer this type, but it is possible
9566+
// to infer a type that contains it, e.g. for a binding pattern like [foo] or { foo }. In such cases,
9567+
// widening of the binding pattern type substitutes a regular any for the non-inferrable any.
9568+
return includePatternInType ? nonInferrableAnyType : anyType;
95649569
}
95659570

95669571
// Return the type implied by an object binding pattern
@@ -22657,7 +22662,10 @@ namespace ts {
2265722662
//
2265822663
// This flag is infectious; if we produce Box<never> (where never is silentNeverType), Box<never> is
2265922664
// also non-inferrable.
22660-
if (getObjectFlags(source) & ObjectFlags.NonInferrableType) {
22665+
//
22666+
// As a special case, also ignore nonInferrableAnyType, which is a special form of the any type
22667+
// used as a stand-in for binding elements when they are being inferred.
22668+
if (getObjectFlags(source) & ObjectFlags.NonInferrableType || source === nonInferrableAnyType) {
2266122669
return;
2266222670
}
2266322671
if (!inference.isFixed) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//// [inferStringLiteralUnionForBindingElement.ts]
2+
declare function func<T extends string>(arg: { keys: T[] }): { readonly keys: T[]; readonly firstKey: T; };
3+
4+
function func1() {
5+
const { firstKey } = func({keys: ["aa", "bb"]})
6+
const a: "aa" | "bb" = firstKey;
7+
8+
const { keys } = func({keys: ["aa", "bb"]})
9+
const b: ("aa" | "bb")[] = keys;
10+
}
11+
12+
function func2() {
13+
const { keys, firstKey } = func({keys: ["aa", "bb"]})
14+
const a: "aa" | "bb" = firstKey;
15+
const b: ("aa" | "bb")[] = keys;
16+
}
17+
18+
function func3() {
19+
const x = func({keys: ["aa", "bb"]})
20+
const a: "aa" | "bb" = x.firstKey;
21+
const b: ("aa" | "bb")[] = x.keys;
22+
}
23+
24+
25+
//// [inferStringLiteralUnionForBindingElement.js]
26+
function func1() {
27+
var firstKey = func({ keys: ["aa", "bb"] }).firstKey;
28+
var a = firstKey;
29+
var keys = func({ keys: ["aa", "bb"] }).keys;
30+
var b = keys;
31+
}
32+
function func2() {
33+
var _a = func({ keys: ["aa", "bb"] }), keys = _a.keys, firstKey = _a.firstKey;
34+
var a = firstKey;
35+
var b = keys;
36+
}
37+
function func3() {
38+
var x = func({ keys: ["aa", "bb"] });
39+
var a = x.firstKey;
40+
var b = x.keys;
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
=== tests/cases/compiler/inferStringLiteralUnionForBindingElement.ts ===
2+
declare function func<T extends string>(arg: { keys: T[] }): { readonly keys: T[]; readonly firstKey: T; };
3+
>func : Symbol(func, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 0))
4+
>T : Symbol(T, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 22))
5+
>arg : Symbol(arg, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 40))
6+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 46))
7+
>T : Symbol(T, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 22))
8+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 62))
9+
>T : Symbol(T, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 22))
10+
>firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 82))
11+
>T : Symbol(T, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 22))
12+
13+
function func1() {
14+
>func1 : Symbol(func1, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 107))
15+
16+
const { firstKey } = func({keys: ["aa", "bb"]})
17+
>firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 3, 11))
18+
>func : Symbol(func, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 0))
19+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 3, 31))
20+
21+
const a: "aa" | "bb" = firstKey;
22+
>a : Symbol(a, Decl(inferStringLiteralUnionForBindingElement.ts, 4, 9))
23+
>firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 3, 11))
24+
25+
const { keys } = func({keys: ["aa", "bb"]})
26+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 6, 11))
27+
>func : Symbol(func, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 0))
28+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 6, 27))
29+
30+
const b: ("aa" | "bb")[] = keys;
31+
>b : Symbol(b, Decl(inferStringLiteralUnionForBindingElement.ts, 7, 9))
32+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 6, 11))
33+
}
34+
35+
function func2() {
36+
>func2 : Symbol(func2, Decl(inferStringLiteralUnionForBindingElement.ts, 8, 1))
37+
38+
const { keys, firstKey } = func({keys: ["aa", "bb"]})
39+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 11, 11))
40+
>firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 11, 17))
41+
>func : Symbol(func, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 0))
42+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 11, 37))
43+
44+
const a: "aa" | "bb" = firstKey;
45+
>a : Symbol(a, Decl(inferStringLiteralUnionForBindingElement.ts, 12, 9))
46+
>firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 11, 17))
47+
48+
const b: ("aa" | "bb")[] = keys;
49+
>b : Symbol(b, Decl(inferStringLiteralUnionForBindingElement.ts, 13, 9))
50+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 11, 11))
51+
}
52+
53+
function func3() {
54+
>func3 : Symbol(func3, Decl(inferStringLiteralUnionForBindingElement.ts, 14, 1))
55+
56+
const x = func({keys: ["aa", "bb"]})
57+
>x : Symbol(x, Decl(inferStringLiteralUnionForBindingElement.ts, 17, 9))
58+
>func : Symbol(func, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 0))
59+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 17, 20))
60+
61+
const a: "aa" | "bb" = x.firstKey;
62+
>a : Symbol(a, Decl(inferStringLiteralUnionForBindingElement.ts, 18, 9))
63+
>x.firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 82))
64+
>x : Symbol(x, Decl(inferStringLiteralUnionForBindingElement.ts, 17, 9))
65+
>firstKey : Symbol(firstKey, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 82))
66+
67+
const b: ("aa" | "bb")[] = x.keys;
68+
>b : Symbol(b, Decl(inferStringLiteralUnionForBindingElement.ts, 19, 9))
69+
>x.keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 62))
70+
>x : Symbol(x, Decl(inferStringLiteralUnionForBindingElement.ts, 17, 9))
71+
>keys : Symbol(keys, Decl(inferStringLiteralUnionForBindingElement.ts, 0, 62))
72+
}
73+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
=== tests/cases/compiler/inferStringLiteralUnionForBindingElement.ts ===
2+
declare function func<T extends string>(arg: { keys: T[] }): { readonly keys: T[]; readonly firstKey: T; };
3+
>func : <T extends string>(arg: { keys: T[];}) => { readonly keys: T[]; readonly firstKey: T;}
4+
>arg : { keys: T[]; }
5+
>keys : T[]
6+
>keys : T[]
7+
>firstKey : T
8+
9+
function func1() {
10+
>func1 : () => void
11+
12+
const { firstKey } = func({keys: ["aa", "bb"]})
13+
>firstKey : "aa" | "bb"
14+
>func({keys: ["aa", "bb"]}) : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
15+
>func : <T extends string>(arg: { keys: T[]; }) => { readonly keys: T[]; readonly firstKey: T; }
16+
>{keys: ["aa", "bb"]} : { keys: ("aa" | "bb")[]; }
17+
>keys : ("aa" | "bb")[]
18+
>["aa", "bb"] : ("aa" | "bb")[]
19+
>"aa" : "aa"
20+
>"bb" : "bb"
21+
22+
const a: "aa" | "bb" = firstKey;
23+
>a : "aa" | "bb"
24+
>firstKey : "aa" | "bb"
25+
26+
const { keys } = func({keys: ["aa", "bb"]})
27+
>keys : ("aa" | "bb")[]
28+
>func({keys: ["aa", "bb"]}) : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
29+
>func : <T extends string>(arg: { keys: T[]; }) => { readonly keys: T[]; readonly firstKey: T; }
30+
>{keys: ["aa", "bb"]} : { keys: ("aa" | "bb")[]; }
31+
>keys : ("aa" | "bb")[]
32+
>["aa", "bb"] : ("aa" | "bb")[]
33+
>"aa" : "aa"
34+
>"bb" : "bb"
35+
36+
const b: ("aa" | "bb")[] = keys;
37+
>b : ("aa" | "bb")[]
38+
>keys : ("aa" | "bb")[]
39+
}
40+
41+
function func2() {
42+
>func2 : () => void
43+
44+
const { keys, firstKey } = func({keys: ["aa", "bb"]})
45+
>keys : ("aa" | "bb")[]
46+
>firstKey : "aa" | "bb"
47+
>func({keys: ["aa", "bb"]}) : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
48+
>func : <T extends string>(arg: { keys: T[]; }) => { readonly keys: T[]; readonly firstKey: T; }
49+
>{keys: ["aa", "bb"]} : { keys: ("aa" | "bb")[]; }
50+
>keys : ("aa" | "bb")[]
51+
>["aa", "bb"] : ("aa" | "bb")[]
52+
>"aa" : "aa"
53+
>"bb" : "bb"
54+
55+
const a: "aa" | "bb" = firstKey;
56+
>a : "aa" | "bb"
57+
>firstKey : "aa" | "bb"
58+
59+
const b: ("aa" | "bb")[] = keys;
60+
>b : ("aa" | "bb")[]
61+
>keys : ("aa" | "bb")[]
62+
}
63+
64+
function func3() {
65+
>func3 : () => void
66+
67+
const x = func({keys: ["aa", "bb"]})
68+
>x : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
69+
>func({keys: ["aa", "bb"]}) : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
70+
>func : <T extends string>(arg: { keys: T[]; }) => { readonly keys: T[]; readonly firstKey: T; }
71+
>{keys: ["aa", "bb"]} : { keys: ("aa" | "bb")[]; }
72+
>keys : ("aa" | "bb")[]
73+
>["aa", "bb"] : ("aa" | "bb")[]
74+
>"aa" : "aa"
75+
>"bb" : "bb"
76+
77+
const a: "aa" | "bb" = x.firstKey;
78+
>a : "aa" | "bb"
79+
>x.firstKey : "aa" | "bb"
80+
>x : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
81+
>firstKey : "aa" | "bb"
82+
83+
const b: ("aa" | "bb")[] = x.keys;
84+
>b : ("aa" | "bb")[]
85+
>x.keys : ("aa" | "bb")[]
86+
>x : { readonly keys: ("aa" | "bb")[]; readonly firstKey: "aa" | "bb"; }
87+
>keys : ("aa" | "bb")[]
88+
}
89+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
declare function func<T extends string>(arg: { keys: T[] }): { readonly keys: T[]; readonly firstKey: T; };
2+
3+
function func1() {
4+
const { firstKey } = func({keys: ["aa", "bb"]})
5+
const a: "aa" | "bb" = firstKey;
6+
7+
const { keys } = func({keys: ["aa", "bb"]})
8+
const b: ("aa" | "bb")[] = keys;
9+
}
10+
11+
function func2() {
12+
const { keys, firstKey } = func({keys: ["aa", "bb"]})
13+
const a: "aa" | "bb" = firstKey;
14+
const b: ("aa" | "bb")[] = keys;
15+
}
16+
17+
function func3() {
18+
const x = func({keys: ["aa", "bb"]})
19+
const a: "aa" | "bb" = x.firstKey;
20+
const b: ("aa" | "bb")[] = x.keys;
21+
}

0 commit comments

Comments
 (0)
Please sign in to comment.