Skip to content

Commit 1192a18

Browse files
authored
Merge pull request #22323 from Microsoft/checkInferredConstraints
Check inferred constraints for 'infer X' type variables
2 parents 70818ae + 07ed899 commit 1192a18

File tree

7 files changed

+376
-195
lines changed

7 files changed

+376
-195
lines changed

src/compiler/checker.ts

+73-70
Large diffs are not rendered by default.

src/compiler/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3966,7 +3966,8 @@ namespace ts {
39663966

39673967
/* @internal */
39683968
export interface InferenceContext extends TypeMapper {
3969-
signature: Signature; // Generic signature for which inferences are made
3969+
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
3970+
signature: Signature; // Generic signature for which inferences are made (if any)
39703971
inferences: InferenceInfo[]; // Inferences made for each type parameter
39713972
flags: InferenceFlags; // Inference flags
39723973
compareTypes: TypeComparer; // Type comparer function

tests/baselines/reference/inferTypes1.errors.txt

+18-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS2304: C
1717
tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'.
1818
tests/cases/conformance/types/conditional/inferTypes1.ts(81,44): error TS2344: Type 'U' does not satisfy the constraint 'string'.
1919
Type 'number' is not assignable to type 'string'.
20-
tests/cases/conformance/types/conditional/inferTypes1.ts(134,40): error TS2322: Type 'T' is not assignable to type 'string'.
20+
tests/cases/conformance/types/conditional/inferTypes1.ts(143,40): error TS2322: Type 'T' is not assignable to type 'string'.
2121

2222

2323
==== tests/cases/conformance/types/conditional/inferTypes1.ts (16 errors) ====
@@ -144,6 +144,15 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(134,40): error TS2322:
144144
type T77<T> = T extends T76<infer X, infer Y> ? T76<X, Y> : never;
145145
type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
146146

147+
type Foo<T extends string, U extends T> = [T, U];
148+
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
149+
150+
type T90 = Bar<[string, string]>; // [string, string]
151+
type T91 = Bar<[string, "a"]>; // [string, "a"]
152+
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
153+
type T93 = Bar<["a", string]>; // never
154+
type T94 = Bar<[number, number]>; // never
155+
147156
// Example from #21496
148157

149158
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
@@ -206,4 +215,12 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(134,40): error TS2322:
206215

207216
type T80 = MatchingKeys<test, void>;
208217
type T81 = VoidKeys<test>;
218+
219+
// Repro from #22221
220+
221+
type MustBeString<T extends string> = T;
222+
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
223+
224+
type Test1 = EnsureIsString<"hello">; // "hello"
225+
type Test2 = EnsureIsString<42>; // never
209226

tests/baselines/reference/inferTypes1.js

+17
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ type T76<T extends T[], U extends T> = { x: T };
8888
type T77<T> = T extends T76<infer X, infer Y> ? T76<X, Y> : never;
8989
type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
9090

91+
type Foo<T extends string, U extends T> = [T, U];
92+
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
93+
94+
type T90 = Bar<[string, string]>; // [string, string]
95+
type T91 = Bar<[string, "a"]>; // [string, "a"]
96+
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
97+
type T93 = Bar<["a", string]>; // never
98+
type T94 = Bar<[number, number]>; // never
99+
91100
// Example from #21496
92101

93102
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
@@ -148,6 +157,14 @@ interface test {
148157

149158
type T80 = MatchingKeys<test, void>;
150159
type T81 = VoidKeys<test>;
160+
161+
// Repro from #22221
162+
163+
type MustBeString<T extends string> = T;
164+
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
165+
166+
type Test1 = EnsureIsString<"hello">; // "hello"
167+
type Test2 = EnsureIsString<42>; // never
151168

152169

153170
//// [inferTypes1.js]

0 commit comments

Comments
 (0)