Skip to content

Commit

Permalink
Merge pull request #31137 from Microsoft/fixConditionalInference
Browse files Browse the repository at this point in the history
Fix conditional type inference involving any or unknown
  • Loading branch information
ahejlsberg committed Apr 30, 2019
2 parents a539887 + 31551fd commit be409fa
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/compiler/checker.ts
Expand Up @@ -10386,11 +10386,11 @@ namespace ts {
// We attempt to resolve the conditional type only when the check and extends types are non-generic
if (!checkTypeInstantiable && !maybeTypeOfKind(inferredExtendsType, TypeFlags.Instantiable | TypeFlags.GenericMappedType)) {
if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown) {
return trueType;
return combinedMapper ? instantiateType(root.trueType, combinedMapper) : trueType;
}
// Return union of trueType and falseType for 'any' since it matches anything
if (checkType.flags & TypeFlags.Any) {
return getUnionType([instantiateType(root.trueType, combinedMapper || mapper), falseType]);
return getUnionType([combinedMapper ? instantiateType(root.trueType, combinedMapper) : trueType, falseType]);
}
// Return falseType for a definitely false extends check. We check an instantiations of the two
// types with type parameters mapped to the wildcard type, the most permissive instantiations
Expand All @@ -10405,7 +10405,7 @@ namespace ts {
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
// doesn't immediately resolve to 'string' instead of being deferred.
if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
return instantiateType(root.trueType, combinedMapper || mapper);
return combinedMapper ? instantiateType(root.trueType, combinedMapper) : trueType;
}
}
// Return a deferred type for a check that is neither definitely true nor definitely false
Expand Down
10 changes: 10 additions & 0 deletions tests/baselines/reference/inferTypes2.js
Expand Up @@ -12,6 +12,14 @@ export declare function foo2<T>(obj: T): T extends { [K in keyof BadNested<infer
export function bar2<T>(obj: T) {
return foo2(obj);
}

// Repros from #31099

type Weird = any extends infer U ? U : never;
type AlsoWeird = unknown extends infer U ? U : never;

const a: Weird = null;
const b: string = a;


//// [inferTypes2.js]
Expand All @@ -26,6 +34,8 @@ function bar2(obj) {
return foo2(obj);
}
exports.bar2 = bar2;
var a = null;
var b = a;


//// [inferTypes2.d.ts]
Expand Down
20 changes: 20 additions & 0 deletions tests/baselines/reference/inferTypes2.symbols
Expand Up @@ -53,3 +53,23 @@ export function bar2<T>(obj: T) {
>obj : Symbol(obj, Decl(inferTypes2.ts, 10, 24))
}

// Repros from #31099

type Weird = any extends infer U ? U : never;
>Weird : Symbol(Weird, Decl(inferTypes2.ts, 12, 1))
>U : Symbol(U, Decl(inferTypes2.ts, 16, 30))
>U : Symbol(U, Decl(inferTypes2.ts, 16, 30))

type AlsoWeird = unknown extends infer U ? U : never;
>AlsoWeird : Symbol(AlsoWeird, Decl(inferTypes2.ts, 16, 45))
>U : Symbol(U, Decl(inferTypes2.ts, 17, 38))
>U : Symbol(U, Decl(inferTypes2.ts, 17, 38))

const a: Weird = null;
>a : Symbol(a, Decl(inferTypes2.ts, 19, 5))
>Weird : Symbol(Weird, Decl(inferTypes2.ts, 12, 1))

const b: string = a;
>b : Symbol(b, Decl(inferTypes2.ts, 20, 5))
>a : Symbol(a, Decl(inferTypes2.ts, 19, 5))

16 changes: 16 additions & 0 deletions tests/baselines/reference/inferTypes2.types
Expand Up @@ -33,3 +33,19 @@ export function bar2<T>(obj: T) {
>obj : T
}

// Repros from #31099

type Weird = any extends infer U ? U : never;
>Weird : any

type AlsoWeird = unknown extends infer U ? U : never;
>AlsoWeird : unknown

const a: Weird = null;
>a : any
>null : null

const b: string = a;
>b : string
>a : any

8 changes: 8 additions & 0 deletions tests/cases/conformance/types/conditional/inferTypes2.ts
Expand Up @@ -14,3 +14,11 @@ export declare function foo2<T>(obj: T): T extends { [K in keyof BadNested<infer
export function bar2<T>(obj: T) {
return foo2(obj);
}

// Repros from #31099

type Weird = any extends infer U ? U : never;
type AlsoWeird = unknown extends infer U ? U : never;

const a: Weird = null;
const b: string = a;

0 comments on commit be409fa

Please sign in to comment.