Skip to content

Commit b0f050f

Browse files
authored
Merge pull request #32260 from microsoft/fix32169
Include conditional types in top-level type parameter check
2 parents fb50920 + 0d99292 commit b0f050f

File tree

5 files changed

+78
-1
lines changed

5 files changed

+78
-1
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15286,7 +15286,11 @@ namespace ts {
1528615286
}
1528715287

1528815288
function isTypeParameterAtTopLevel(type: Type, typeParameter: TypeParameter): boolean {
15289-
return type === typeParameter || !!(type.flags & TypeFlags.UnionOrIntersection) && some((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
15289+
return !!(type === typeParameter ||
15290+
type.flags & TypeFlags.UnionOrIntersection && some((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter)) ||
15291+
type.flags & TypeFlags.Conditional && (
15292+
isTypeParameterAtTopLevel(getTrueTypeFromConditionalType(<ConditionalType>type), typeParameter) ||
15293+
isTypeParameterAtTopLevel(getFalseTypeFromConditionalType(<ConditionalType>type), typeParameter)));
1529015294
}
1529115295

1529215296
/** Create an object with properties named in the string literal type. Every property has type `any` */

tests/baselines/reference/literalTypeWidening.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ function test<T extends { a: string, b: string }>(obj: T): T {
135135
let { a, ...rest } = obj;
136136
return { a: 'hello', ...rest } as T;
137137
}
138+
139+
// Repro from #32169
140+
141+
declare function f<T>(x: T): NonNullable<T>;
142+
enum E { A, B }
143+
const a = f(E.A);
144+
const b: E.A = a;
138145

139146

140147
//// [literalTypeWidening.js]
@@ -267,3 +274,10 @@ function test(obj) {
267274
var a = obj.a, rest = __rest(obj, ["a"]);
268275
return __assign({ a: 'hello' }, rest);
269276
}
277+
var E;
278+
(function (E) {
279+
E[E["A"] = 0] = "A";
280+
E[E["B"] = 1] = "B";
281+
})(E || (E = {}));
282+
var a = f(E.A);
283+
var b = a;

tests/baselines/reference/literalTypeWidening.symbols

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,3 +422,31 @@ function test<T extends { a: string, b: string }>(obj: T): T {
422422
>T : Symbol(T, Decl(literalTypeWidening.ts, 132, 14))
423423
}
424424

425+
// Repro from #32169
426+
427+
declare function f<T>(x: T): NonNullable<T>;
428+
>f : Symbol(f, Decl(literalTypeWidening.ts, 135, 1))
429+
>T : Symbol(T, Decl(literalTypeWidening.ts, 139, 19))
430+
>x : Symbol(x, Decl(literalTypeWidening.ts, 139, 22))
431+
>T : Symbol(T, Decl(literalTypeWidening.ts, 139, 19))
432+
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
433+
>T : Symbol(T, Decl(literalTypeWidening.ts, 139, 19))
434+
435+
enum E { A, B }
436+
>E : Symbol(E, Decl(literalTypeWidening.ts, 139, 44))
437+
>A : Symbol(E.A, Decl(literalTypeWidening.ts, 140, 8))
438+
>B : Symbol(E.B, Decl(literalTypeWidening.ts, 140, 11))
439+
440+
const a = f(E.A);
441+
>a : Symbol(a, Decl(literalTypeWidening.ts, 141, 5))
442+
>f : Symbol(f, Decl(literalTypeWidening.ts, 135, 1))
443+
>E.A : Symbol(E.A, Decl(literalTypeWidening.ts, 140, 8))
444+
>E : Symbol(E, Decl(literalTypeWidening.ts, 139, 44))
445+
>A : Symbol(E.A, Decl(literalTypeWidening.ts, 140, 8))
446+
447+
const b: E.A = a;
448+
>b : Symbol(b, Decl(literalTypeWidening.ts, 142, 5))
449+
>E : Symbol(E, Decl(literalTypeWidening.ts, 139, 44))
450+
>A : Symbol(E.A, Decl(literalTypeWidening.ts, 140, 8))
451+
>a : Symbol(a, Decl(literalTypeWidening.ts, 141, 5))
452+

tests/baselines/reference/literalTypeWidening.types

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,27 @@ function test<T extends { a: string, b: string }>(obj: T): T {
454454
>rest : Pick<T, Exclude<keyof T, "a">>
455455
}
456456

457+
// Repro from #32169
458+
459+
declare function f<T>(x: T): NonNullable<T>;
460+
>f : <T>(x: T) => NonNullable<T>
461+
>x : T
462+
463+
enum E { A, B }
464+
>E : E
465+
>A : E.A
466+
>B : E.B
467+
468+
const a = f(E.A);
469+
>a : E.A
470+
>f(E.A) : E.A
471+
>f : <T>(x: T) => NonNullable<T>
472+
>E.A : E.A
473+
>E : typeof E
474+
>A : E.A
475+
476+
const b: E.A = a;
477+
>b : E.A
478+
>E : any
479+
>a : E.A
480+

tests/cases/conformance/types/literal/literalTypeWidening.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,10 @@ function test<T extends { a: string, b: string }>(obj: T): T {
134134
let { a, ...rest } = obj;
135135
return { a: 'hello', ...rest } as T;
136136
}
137+
138+
// Repro from #32169
139+
140+
declare function f<T>(x: T): NonNullable<T>;
141+
enum E { A, B }
142+
const a = f(E.A);
143+
const b: E.A = a;

0 commit comments

Comments
 (0)