mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-10 06:41:59 -06:00
Merge pull request #6330 from weswigham/restorative-narrowing
Fix #6277
This commit is contained in:
commit
403a93d21f
@ -6722,10 +6722,6 @@ namespace ts {
|
||||
if (typeInfo && typeInfo.type === undefinedType) {
|
||||
return type;
|
||||
}
|
||||
// If the type to be narrowed is any and we're checking a primitive with assumeTrue=true, return the primitive
|
||||
if (!!(type.flags & TypeFlags.Any) && typeInfo && assumeTrue) {
|
||||
return typeInfo.type;
|
||||
}
|
||||
let flags: TypeFlags;
|
||||
if (typeInfo) {
|
||||
flags = typeInfo.flags;
|
||||
@ -6736,6 +6732,10 @@ namespace ts {
|
||||
}
|
||||
// At this point we can bail if it's not a union
|
||||
if (!(type.flags & TypeFlags.Union)) {
|
||||
// If we're on the true branch and the type is a subtype, we should return the primitive type
|
||||
if (assumeTrue && typeInfo && isTypeSubtypeOf(typeInfo.type, type)) {
|
||||
return typeInfo.type;
|
||||
}
|
||||
// If the active non-union type would be removed from a union by this type guard, return an empty union
|
||||
return filterUnion(type) ? type : emptyUnionType;
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
//// [typeGuardOfFormTypeOfPrimitiveSubtype.ts]
|
||||
let a: {};
|
||||
let b: {toString(): string};
|
||||
if (typeof a === "number") {
|
||||
let c: number = a;
|
||||
}
|
||||
if (typeof a === "string") {
|
||||
let c: string = a;
|
||||
}
|
||||
if (typeof a === "boolean") {
|
||||
let c: boolean = a;
|
||||
}
|
||||
|
||||
if (typeof b === "number") {
|
||||
let c: number = b;
|
||||
}
|
||||
if (typeof b === "string") {
|
||||
let c: string = b;
|
||||
}
|
||||
if (typeof b === "boolean") {
|
||||
let c: boolean = b;
|
||||
}
|
||||
|
||||
|
||||
//// [typeGuardOfFormTypeOfPrimitiveSubtype.js]
|
||||
var a;
|
||||
var b;
|
||||
if (typeof a === "number") {
|
||||
var c = a;
|
||||
}
|
||||
if (typeof a === "string") {
|
||||
var c = a;
|
||||
}
|
||||
if (typeof a === "boolean") {
|
||||
var c = a;
|
||||
}
|
||||
if (typeof b === "number") {
|
||||
var c = b;
|
||||
}
|
||||
if (typeof b === "string") {
|
||||
var c = b;
|
||||
}
|
||||
if (typeof b === "boolean") {
|
||||
var c = b;
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfPrimitiveSubtype.ts ===
|
||||
let a: {};
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
|
||||
let b: {toString(): string};
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
>toString : Symbol(toString, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 8))
|
||||
|
||||
if (typeof a === "number") {
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
|
||||
let c: number = a;
|
||||
>c : Symbol(c, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 3, 7))
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
}
|
||||
if (typeof a === "string") {
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
|
||||
let c: string = a;
|
||||
>c : Symbol(c, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 6, 7))
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
}
|
||||
if (typeof a === "boolean") {
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
|
||||
let c: boolean = a;
|
||||
>c : Symbol(c, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 9, 7))
|
||||
>a : Symbol(a, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 0, 3))
|
||||
}
|
||||
|
||||
if (typeof b === "number") {
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
|
||||
let c: number = b;
|
||||
>c : Symbol(c, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 13, 7))
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
}
|
||||
if (typeof b === "string") {
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
|
||||
let c: string = b;
|
||||
>c : Symbol(c, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 16, 7))
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
}
|
||||
if (typeof b === "boolean") {
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
|
||||
let c: boolean = b;
|
||||
>c : Symbol(c, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 19, 7))
|
||||
>b : Symbol(b, Decl(typeGuardOfFormTypeOfPrimitiveSubtype.ts, 1, 3))
|
||||
}
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfPrimitiveSubtype.ts ===
|
||||
let a: {};
|
||||
>a : {}
|
||||
|
||||
let b: {toString(): string};
|
||||
>b : { toString(): string; }
|
||||
>toString : () => string
|
||||
|
||||
if (typeof a === "number") {
|
||||
>typeof a === "number" : boolean
|
||||
>typeof a : string
|
||||
>a : {}
|
||||
>"number" : string
|
||||
|
||||
let c: number = a;
|
||||
>c : number
|
||||
>a : number
|
||||
}
|
||||
if (typeof a === "string") {
|
||||
>typeof a === "string" : boolean
|
||||
>typeof a : string
|
||||
>a : {}
|
||||
>"string" : string
|
||||
|
||||
let c: string = a;
|
||||
>c : string
|
||||
>a : string
|
||||
}
|
||||
if (typeof a === "boolean") {
|
||||
>typeof a === "boolean" : boolean
|
||||
>typeof a : string
|
||||
>a : {}
|
||||
>"boolean" : string
|
||||
|
||||
let c: boolean = a;
|
||||
>c : boolean
|
||||
>a : boolean
|
||||
}
|
||||
|
||||
if (typeof b === "number") {
|
||||
>typeof b === "number" : boolean
|
||||
>typeof b : string
|
||||
>b : { toString(): string; }
|
||||
>"number" : string
|
||||
|
||||
let c: number = b;
|
||||
>c : number
|
||||
>b : number
|
||||
}
|
||||
if (typeof b === "string") {
|
||||
>typeof b === "string" : boolean
|
||||
>typeof b : string
|
||||
>b : { toString(): string; }
|
||||
>"string" : string
|
||||
|
||||
let c: string = b;
|
||||
>c : string
|
||||
>b : string
|
||||
}
|
||||
if (typeof b === "boolean") {
|
||||
>typeof b === "boolean" : boolean
|
||||
>typeof b : string
|
||||
>b : { toString(): string; }
|
||||
>"boolean" : string
|
||||
|
||||
let c: boolean = b;
|
||||
>c : boolean
|
||||
>b : boolean
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
let a: {};
|
||||
let b: {toString(): string};
|
||||
if (typeof a === "number") {
|
||||
let c: number = a;
|
||||
}
|
||||
if (typeof a === "string") {
|
||||
let c: string = a;
|
||||
}
|
||||
if (typeof a === "boolean") {
|
||||
let c: boolean = a;
|
||||
}
|
||||
|
||||
if (typeof b === "number") {
|
||||
let c: number = b;
|
||||
}
|
||||
if (typeof b === "string") {
|
||||
let c: string = b;
|
||||
}
|
||||
if (typeof b === "boolean") {
|
||||
let c: boolean = b;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user