Merge pull request #31137 from Microsoft/fixConditionalInference

Fix conditional type inference involving any or unknown
This commit is contained in:
Anders Hejlsberg
2019-04-30 06:26:02 -07:00
committed by GitHub
5 changed files with 57 additions and 3 deletions

View File

@@ -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
@@ -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

View File

@@ -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]
@@ -26,6 +34,8 @@ function bar2(obj) {
return foo2(obj);
}
exports.bar2 = bar2;
var a = null;
var b = a;
//// [inferTypes2.d.ts]

View File

@@ -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))

View File

@@ -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

View File

@@ -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;