Improved handing of union types in type guards
This commit is contained in:
parent
bf46e50f89
commit
59e266de02
|
@ -4709,13 +4709,21 @@ module ts {
|
|||
if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
|
||||
return type;
|
||||
}
|
||||
// Target type is type of prototype property
|
||||
var prototypeProperty = getPropertyOfType(rightType, "prototype");
|
||||
if (!prototypeProperty) {
|
||||
return type;
|
||||
}
|
||||
var prototypeType = getTypeOfSymbol(prototypeProperty);
|
||||
// Narrow to type of prototype property if it is a subtype of current type
|
||||
return isTypeSubtypeOf(prototypeType, type) ? prototypeType : type;
|
||||
var targetType = getTypeOfSymbol(prototypeProperty);
|
||||
// Narrow to target type if it is a subtype of current type
|
||||
if (isTypeSubtypeOf(targetType, type)) {
|
||||
return targetType;
|
||||
}
|
||||
// If current type is a union type, remove all constituents that aren't subtypes of target type
|
||||
if (type.flags && TypeFlags.Union) {
|
||||
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, targetType)));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
// Narrow the given type based on the given expression having the assumed boolean value
|
||||
|
|
23
tests/baselines/reference/TypeGuardWithArrayUnion.js
Normal file
23
tests/baselines/reference/TypeGuardWithArrayUnion.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
//// [TypeGuardWithArrayUnion.ts]
|
||||
class Message {
|
||||
value: string;
|
||||
}
|
||||
|
||||
function saySize(message: Message | Message[]) {
|
||||
if (message instanceof Array) {
|
||||
return message.length; // Should have type Message[] here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [TypeGuardWithArrayUnion.js]
|
||||
var Message = (function () {
|
||||
function Message() {
|
||||
}
|
||||
return Message;
|
||||
})();
|
||||
function saySize(message) {
|
||||
if (message instanceof Array) {
|
||||
return message.length; // Should have type Message[] here
|
||||
}
|
||||
}
|
26
tests/baselines/reference/TypeGuardWithArrayUnion.types
Normal file
26
tests/baselines/reference/TypeGuardWithArrayUnion.types
Normal file
|
@ -0,0 +1,26 @@
|
|||
=== tests/cases/conformance/expressions/typeGuards/TypeGuardWithArrayUnion.ts ===
|
||||
class Message {
|
||||
>Message : Message
|
||||
|
||||
value: string;
|
||||
>value : string
|
||||
}
|
||||
|
||||
function saySize(message: Message | Message[]) {
|
||||
>saySize : (message: Message | Message[]) => number
|
||||
>message : Message | Message[]
|
||||
>Message : Message
|
||||
>Message : Message
|
||||
|
||||
if (message instanceof Array) {
|
||||
>message instanceof Array : boolean
|
||||
>message : Message | Message[]
|
||||
>Array : ArrayConstructor
|
||||
|
||||
return message.length; // Should have type Message[] here
|
||||
>message.length : number
|
||||
>message : Message[]
|
||||
>length : number
|
||||
}
|
||||
}
|
||||
|
|
@ -124,9 +124,9 @@ var r2: D1 | C2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
|
|||
>r2 : C2 | D1
|
||||
>D1 : D1
|
||||
>C2 : C2
|
||||
>c2Ord1 instanceof C1 && c2Ord1 : C2 | D1
|
||||
>c2Ord1 instanceof C1 && c2Ord1 : D1
|
||||
>c2Ord1 instanceof C1 : boolean
|
||||
>c2Ord1 : C2 | D1
|
||||
>C1 : typeof C1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1 : D1
|
||||
|
||||
|
|
|
@ -154,9 +154,9 @@ var r2: D1 | C2 = c2Ord1 instanceof c1 && c2Ord1; // C2 | D1
|
|||
>r2 : C2 | D1
|
||||
>D1 : D1
|
||||
>C2 : C2
|
||||
>c2Ord1 instanceof c1 && c2Ord1 : C2 | D1
|
||||
>c2Ord1 instanceof c1 && c2Ord1 : D1
|
||||
>c2Ord1 instanceof c1 : boolean
|
||||
>c2Ord1 : C2 | D1
|
||||
>c1 : C1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1 : D1
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class Message {
|
||||
value: string;
|
||||
}
|
||||
|
||||
function saySize(message: Message | Message[]) {
|
||||
if (message instanceof Array) {
|
||||
return message.length; // Should have type Message[] here
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue