Skip to content

Commit c33d926

Browse files
committed
Fixed substition flow types of NoInfer types
1 parent a709f98 commit c33d926

File tree

5 files changed

+310
-1
lines changed

5 files changed

+310
-1
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16773,7 +16773,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1677316773
}
1677416774
node = parent;
1677516775
}
16776-
return constraints ? getSubstitutionType(type, getIntersectionType(constraints)) : type;
16776+
if (!constraints) {
16777+
return type;
16778+
}
16779+
if (isNoInferType(type)) {
16780+
constraints = append(constraints, (type as SubstitutionType).baseType);
16781+
return getNoInferType(getIntersectionType(constraints));
16782+
}
16783+
return getSubstitutionType(type, getIntersectionType(constraints));
1677716784
}
1677816785

1677916786
function isJSDocTypeReference(node: Node): node is TypeReferenceNode {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
noInferSubstitutionTypes1.ts(4,24): error TS2345: Argument of type '"rel:7"' is not assignable to parameter of type '"rel:5"'.
2+
noInferSubstitutionTypes1.ts(7,25): error TS2345: Argument of type '"rel:7"' is not assignable to parameter of type '"rel:5"'.
3+
noInferSubstitutionTypes1.ts(10,25): error TS2345: Argument of type '"rel:7"' is not assignable to parameter of type '"rel:5"'.
4+
noInferSubstitutionTypes1.ts(13,26): error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
5+
noInferSubstitutionTypes1.ts(16,27): error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
6+
noInferSubstitutionTypes1.ts(20,27): error TS2345: Argument of type '42' is not assignable to parameter of type '"foo"'.
7+
8+
9+
==== noInferSubstitutionTypes1.ts (6 errors) ====
10+
// https://github.com/microsoft/TypeScript/issues/59826
11+
12+
declare function g<A>(a: A, b: A extends string ? `rel:${NoInfer<A>}` : never): A;
13+
const result1 = g("5", "rel:7"); // error
14+
~~~~~~~
15+
!!! error TS2345: Argument of type '"rel:7"' is not assignable to parameter of type '"rel:5"'.
16+
17+
declare function g2<A>(a: A, b: A extends string ? NoInfer<`rel:${A}`> : never): A;
18+
const result2 = g2("5", "rel:7"); // error
19+
~~~~~~~
20+
!!! error TS2345: Argument of type '"rel:7"' is not assignable to parameter of type '"rel:5"'.
21+
22+
declare function g3<A>(a: A, b: NoInfer<A extends string ? `rel:${A}` : never>): A;
23+
const result3 = g3("5", "rel:7"); // error
24+
~~~~~~~
25+
!!! error TS2345: Argument of type '"rel:7"' is not assignable to parameter of type '"rel:5"'.
26+
27+
declare function h<const A>(a: A, b: A extends string ? NoInfer<A> : never): A;
28+
const result4 = h("foo", "bar"); // error
29+
~~~~~
30+
!!! error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
31+
32+
declare function h2<const A>(a: A, b: NoInfer<A> extends string ? NoInfer<A> : never): A;
33+
const result5 = h2("foo", "bar"); // error
34+
~~~~~
35+
!!! error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
36+
37+
declare function h3<const A>(a: A, b: NoInfer<A> extends string ? A : never): A;
38+
const result6 = h3("foo", "bar"); // no error
39+
const result7 = h3("foo", 42); // error
40+
~~
41+
!!! error TS2345: Argument of type '42' is not assignable to parameter of type '"foo"'.
42+
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferSubstitutionTypes1.ts] ////
2+
3+
=== noInferSubstitutionTypes1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/59826
5+
6+
declare function g<A>(a: A, b: A extends string ? `rel:${NoInfer<A>}` : never): A;
7+
>g : Symbol(g, Decl(noInferSubstitutionTypes1.ts, 0, 0))
8+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 2, 19))
9+
>a : Symbol(a, Decl(noInferSubstitutionTypes1.ts, 2, 22))
10+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 2, 19))
11+
>b : Symbol(b, Decl(noInferSubstitutionTypes1.ts, 2, 27))
12+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 2, 19))
13+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
14+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 2, 19))
15+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 2, 19))
16+
17+
const result1 = g("5", "rel:7"); // error
18+
>result1 : Symbol(result1, Decl(noInferSubstitutionTypes1.ts, 3, 5))
19+
>g : Symbol(g, Decl(noInferSubstitutionTypes1.ts, 0, 0))
20+
21+
declare function g2<A>(a: A, b: A extends string ? NoInfer<`rel:${A}`> : never): A;
22+
>g2 : Symbol(g2, Decl(noInferSubstitutionTypes1.ts, 3, 32))
23+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 5, 20))
24+
>a : Symbol(a, Decl(noInferSubstitutionTypes1.ts, 5, 23))
25+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 5, 20))
26+
>b : Symbol(b, Decl(noInferSubstitutionTypes1.ts, 5, 28))
27+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 5, 20))
28+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
29+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 5, 20))
30+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 5, 20))
31+
32+
const result2 = g2("5", "rel:7"); // error
33+
>result2 : Symbol(result2, Decl(noInferSubstitutionTypes1.ts, 6, 5))
34+
>g2 : Symbol(g2, Decl(noInferSubstitutionTypes1.ts, 3, 32))
35+
36+
declare function g3<A>(a: A, b: NoInfer<A extends string ? `rel:${A}` : never>): A;
37+
>g3 : Symbol(g3, Decl(noInferSubstitutionTypes1.ts, 6, 33))
38+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 8, 20))
39+
>a : Symbol(a, Decl(noInferSubstitutionTypes1.ts, 8, 23))
40+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 8, 20))
41+
>b : Symbol(b, Decl(noInferSubstitutionTypes1.ts, 8, 28))
42+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
43+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 8, 20))
44+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 8, 20))
45+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 8, 20))
46+
47+
const result3 = g3("5", "rel:7"); // error
48+
>result3 : Symbol(result3, Decl(noInferSubstitutionTypes1.ts, 9, 5))
49+
>g3 : Symbol(g3, Decl(noInferSubstitutionTypes1.ts, 6, 33))
50+
51+
declare function h<const A>(a: A, b: A extends string ? NoInfer<A> : never): A;
52+
>h : Symbol(h, Decl(noInferSubstitutionTypes1.ts, 9, 33))
53+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 11, 19))
54+
>a : Symbol(a, Decl(noInferSubstitutionTypes1.ts, 11, 28))
55+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 11, 19))
56+
>b : Symbol(b, Decl(noInferSubstitutionTypes1.ts, 11, 33))
57+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 11, 19))
58+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
59+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 11, 19))
60+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 11, 19))
61+
62+
const result4 = h("foo", "bar"); // error
63+
>result4 : Symbol(result4, Decl(noInferSubstitutionTypes1.ts, 12, 5))
64+
>h : Symbol(h, Decl(noInferSubstitutionTypes1.ts, 9, 33))
65+
66+
declare function h2<const A>(a: A, b: NoInfer<A> extends string ? NoInfer<A> : never): A;
67+
>h2 : Symbol(h2, Decl(noInferSubstitutionTypes1.ts, 12, 32))
68+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 14, 20))
69+
>a : Symbol(a, Decl(noInferSubstitutionTypes1.ts, 14, 29))
70+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 14, 20))
71+
>b : Symbol(b, Decl(noInferSubstitutionTypes1.ts, 14, 34))
72+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
73+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 14, 20))
74+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
75+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 14, 20))
76+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 14, 20))
77+
78+
const result5 = h2("foo", "bar"); // error
79+
>result5 : Symbol(result5, Decl(noInferSubstitutionTypes1.ts, 15, 5))
80+
>h2 : Symbol(h2, Decl(noInferSubstitutionTypes1.ts, 12, 32))
81+
82+
declare function h3<const A>(a: A, b: NoInfer<A> extends string ? A : never): A;
83+
>h3 : Symbol(h3, Decl(noInferSubstitutionTypes1.ts, 15, 33))
84+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 17, 20))
85+
>a : Symbol(a, Decl(noInferSubstitutionTypes1.ts, 17, 29))
86+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 17, 20))
87+
>b : Symbol(b, Decl(noInferSubstitutionTypes1.ts, 17, 34))
88+
>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --))
89+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 17, 20))
90+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 17, 20))
91+
>A : Symbol(A, Decl(noInferSubstitutionTypes1.ts, 17, 20))
92+
93+
const result6 = h3("foo", "bar"); // no error
94+
>result6 : Symbol(result6, Decl(noInferSubstitutionTypes1.ts, 18, 5))
95+
>h3 : Symbol(h3, Decl(noInferSubstitutionTypes1.ts, 15, 33))
96+
97+
const result7 = h3("foo", 42); // error
98+
>result7 : Symbol(result7, Decl(noInferSubstitutionTypes1.ts, 19, 5))
99+
>h3 : Symbol(h3, Decl(noInferSubstitutionTypes1.ts, 15, 33))
100+
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferSubstitutionTypes1.ts] ////
2+
3+
=== noInferSubstitutionTypes1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/59826
5+
6+
declare function g<A>(a: A, b: A extends string ? `rel:${NoInfer<A>}` : never): A;
7+
>g : <A>(a: A, b: A extends string ? `rel:${NoInfer<A>}` : never) => A
8+
> : ^ ^^ ^^ ^^ ^^ ^^^^^
9+
>a : A
10+
> : ^
11+
>b : A extends string ? `rel:${NoInfer<string & A>}` : never
12+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
14+
const result1 = g("5", "rel:7"); // error
15+
>result1 : "5"
16+
> : ^^^
17+
>g("5", "rel:7") : "5"
18+
> : ^^^
19+
>g : <A>(a: A, b: A extends string ? `rel:${NoInfer<A>}` : never) => A
20+
> : ^ ^^ ^^ ^^ ^^ ^^^^^
21+
>"5" : "5"
22+
> : ^^^
23+
>"rel:7" : "rel:7"
24+
> : ^^^^^^^
25+
26+
declare function g2<A>(a: A, b: A extends string ? NoInfer<`rel:${A}`> : never): A;
27+
>g2 : <A>(a: A, b: A extends string ? NoInfer<`rel:${A}`> : never) => A
28+
> : ^ ^^ ^^ ^^ ^^ ^^^^^
29+
>a : A
30+
> : ^
31+
>b : A extends string ? NoInfer<`rel:${A}`> : never
32+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
34+
const result2 = g2("5", "rel:7"); // error
35+
>result2 : "5"
36+
> : ^^^
37+
>g2("5", "rel:7") : "5"
38+
> : ^^^
39+
>g2 : <A>(a: A, b: A extends string ? NoInfer<`rel:${A}`> : never) => A
40+
> : ^ ^^ ^^ ^^ ^^ ^^^^^
41+
>"5" : "5"
42+
> : ^^^
43+
>"rel:7" : "rel:7"
44+
> : ^^^^^^^
45+
46+
declare function g3<A>(a: A, b: NoInfer<A extends string ? `rel:${A}` : never>): A;
47+
>g3 : <A>(a: A, b: NoInfer<A extends string ? `rel:${A}` : never>) => A
48+
> : ^ ^^ ^^ ^^ ^^ ^^^^^
49+
>a : A
50+
> : ^
51+
>b : NoInfer<A extends string ? `rel:${A}` : never>
52+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
54+
const result3 = g3("5", "rel:7"); // error
55+
>result3 : "5"
56+
> : ^^^
57+
>g3("5", "rel:7") : "5"
58+
> : ^^^
59+
>g3 : <A>(a: A, b: NoInfer<A extends string ? `rel:${A}` : never>) => A
60+
> : ^ ^^ ^^ ^^ ^^ ^^^^^
61+
>"5" : "5"
62+
> : ^^^
63+
>"rel:7" : "rel:7"
64+
> : ^^^^^^^
65+
66+
declare function h<const A>(a: A, b: A extends string ? NoInfer<A> : never): A;
67+
>h : <const A>(a: A, b: A extends string ? NoInfer<A> : never) => A
68+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
69+
>a : A
70+
> : ^
71+
>b : A extends string ? NoInfer<string & A> : never
72+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
73+
74+
const result4 = h("foo", "bar"); // error
75+
>result4 : "foo"
76+
> : ^^^^^
77+
>h("foo", "bar") : "foo"
78+
> : ^^^^^
79+
>h : <const A>(a: A, b: A extends string ? NoInfer<A> : never) => A
80+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
81+
>"foo" : "foo"
82+
> : ^^^^^
83+
>"bar" : "bar"
84+
> : ^^^^^
85+
86+
declare function h2<const A>(a: A, b: NoInfer<A> extends string ? NoInfer<A> : never): A;
87+
>h2 : <const A>(a: A, b: NoInfer<A> extends string ? NoInfer<A> : never) => A
88+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
89+
>a : A
90+
> : ^
91+
>b : NoInfer<A> extends string ? NoInfer<string & A> : never
92+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
93+
94+
const result5 = h2("foo", "bar"); // error
95+
>result5 : "foo"
96+
> : ^^^^^
97+
>h2("foo", "bar") : "foo"
98+
> : ^^^^^
99+
>h2 : <const A>(a: A, b: NoInfer<A> extends string ? NoInfer<A> : never) => A
100+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
101+
>"foo" : "foo"
102+
> : ^^^^^
103+
>"bar" : "bar"
104+
> : ^^^^^
105+
106+
declare function h3<const A>(a: A, b: NoInfer<A> extends string ? A : never): A;
107+
>h3 : <const A>(a: A, b: NoInfer<A> extends string ? A : never) => A
108+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
109+
>a : A
110+
> : ^
111+
>b : NoInfer<A> extends string ? A : never
112+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
113+
114+
const result6 = h3("foo", "bar"); // no error
115+
>result6 : "foo" | "bar"
116+
> : ^^^^^^^^^^^^^
117+
>h3("foo", "bar") : "foo" | "bar"
118+
> : ^^^^^^^^^^^^^
119+
>h3 : <const A>(a: A, b: NoInfer<A> extends string ? A : never) => A
120+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
121+
>"foo" : "foo"
122+
> : ^^^^^
123+
>"bar" : "bar"
124+
> : ^^^^^
125+
126+
const result7 = h3("foo", 42); // error
127+
>result7 : "foo"
128+
> : ^^^^^
129+
>h3("foo", 42) : "foo"
130+
> : ^^^^^
131+
>h3 : <const A>(a: A, b: NoInfer<A> extends string ? A : never) => A
132+
> : ^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
133+
>"foo" : "foo"
134+
> : ^^^^^
135+
>42 : 42
136+
> : ^^
137+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/59826
5+
6+
declare function g<A>(a: A, b: A extends string ? `rel:${NoInfer<A>}` : never): A;
7+
const result1 = g("5", "rel:7"); // error
8+
9+
declare function g2<A>(a: A, b: A extends string ? NoInfer<`rel:${A}`> : never): A;
10+
const result2 = g2("5", "rel:7"); // error
11+
12+
declare function g3<A>(a: A, b: NoInfer<A extends string ? `rel:${A}` : never>): A;
13+
const result3 = g3("5", "rel:7"); // error
14+
15+
declare function h<const A>(a: A, b: A extends string ? NoInfer<A> : never): A;
16+
const result4 = h("foo", "bar"); // error
17+
18+
declare function h2<const A>(a: A, b: NoInfer<A> extends string ? NoInfer<A> : never): A;
19+
const result5 = h2("foo", "bar"); // error
20+
21+
declare function h3<const A>(a: A, b: NoInfer<A> extends string ? A : never): A;
22+
const result6 = h3("foo", "bar"); // no error
23+
const result7 = h3("foo", 42); // error

0 commit comments

Comments
 (0)