feedback from pr, new tests
This commit is contained in:
parent
168c664639
commit
9f12bc8a1b
|
@ -6177,27 +6177,6 @@ namespace ts {
|
||||||
Debug.fail("should not get here");
|
Debug.fail("should not get here");
|
||||||
}
|
}
|
||||||
|
|
||||||
// For a union type, remove all constituent types that are of the given type kind (when isOfTypeKind is true)
|
|
||||||
// or not of the given type kind (when isOfTypeKind is false)
|
|
||||||
function removeTypesFromUnionType(type: Type, typeKind: TypeFlags, isOfTypeKind: boolean, allowEmptyUnionResult: boolean): Type {
|
|
||||||
if (type.flags & TypeFlags.Union) {
|
|
||||||
let types = (<UnionType>type).types;
|
|
||||||
if (forEach(types, t => !!(t.flags & typeKind) === isOfTypeKind)) {
|
|
||||||
// Above we checked if we have anything to remove, now use the opposite test to do the removal
|
|
||||||
let narrowedType = getUnionType(filter(types, t => !(t.flags & typeKind) === isOfTypeKind));
|
|
||||||
if (allowEmptyUnionResult || narrowedType !== emptyObjectType) {
|
|
||||||
return narrowedType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (allowEmptyUnionResult && !!(type.flags & typeKind) === isOfTypeKind) {
|
|
||||||
// Use getUnionType(emptyArray) instead of emptyObjectType in case the way empty union types
|
|
||||||
// are represented ever changes.
|
|
||||||
return getUnionType(emptyArray);
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasInitializer(node: VariableLikeDeclaration): boolean {
|
function hasInitializer(node: VariableLikeDeclaration): boolean {
|
||||||
return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(<VariableLikeDeclaration>node.parent.parent));
|
return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(<VariableLikeDeclaration>node.parent.parent));
|
||||||
}
|
}
|
||||||
|
@ -6296,6 +6275,7 @@ namespace ts {
|
||||||
// Get the narrowed type of a given symbol at a given location
|
// Get the narrowed type of a given symbol at a given location
|
||||||
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
|
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
|
||||||
let type = getTypeOfSymbol(symbol);
|
let type = getTypeOfSymbol(symbol);
|
||||||
|
let originalType = type;
|
||||||
// Only narrow when symbol is variable of type any or an object, union, or type parameter type
|
// Only narrow when symbol is variable of type any or an object, union, or type parameter type
|
||||||
if (node && symbol.flags & SymbolFlags.Variable) {
|
if (node && symbol.flags & SymbolFlags.Variable) {
|
||||||
if (isTypeAny(type) || type.flags & (TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) {
|
if (isTypeAny(type) || type.flags & (TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) {
|
||||||
|
@ -6338,10 +6318,6 @@ namespace ts {
|
||||||
// Stop at the first containing function or module declaration
|
// Stop at the first containing function or module declaration
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
// Preserve old top-level behavior - if the branch is really an empty set, revert to prior type
|
|
||||||
if (narrowedType === getUnionType(emptyArray)) {
|
|
||||||
narrowedType = type;
|
|
||||||
}
|
|
||||||
// Use narrowed type if construct contains no assignments to variable
|
// Use narrowed type if construct contains no assignments to variable
|
||||||
if (narrowedType !== type) {
|
if (narrowedType !== type) {
|
||||||
if (isVariableAssignedWithin(symbol, node)) {
|
if (isVariableAssignedWithin(symbol, node)) {
|
||||||
|
@ -6350,6 +6326,11 @@ namespace ts {
|
||||||
type = narrowedType;
|
type = narrowedType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preserve old top-level behavior - if the branch is really an empty set, revert to prior type
|
||||||
|
if (type === getUnionType(emptyArray)) {
|
||||||
|
type = originalType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6369,22 +6350,24 @@ namespace ts {
|
||||||
assumeTrue = !assumeTrue;
|
assumeTrue = !assumeTrue;
|
||||||
}
|
}
|
||||||
let typeInfo = primitiveTypeInfo[right.text];
|
let typeInfo = primitiveTypeInfo[right.text];
|
||||||
// If the type to be narrowed is any and we're affirmatively checking against a primitive, return the primitive
|
// 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) {
|
if (!!(type.flags & TypeFlags.Any) && typeInfo && assumeTrue) {
|
||||||
return typeInfo.type;
|
return typeInfo.type;
|
||||||
}
|
}
|
||||||
// At this point we can bail if it's not a union
|
let flags: TypeFlags;
|
||||||
if (!(type.flags & TypeFlags.Union)) {
|
if (typeInfo) {
|
||||||
return type;
|
flags = typeInfo.flags;
|
||||||
}
|
|
||||||
let flags = typeInfo ? typeInfo.flags : (assumeTrue = !assumeTrue, TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol | TypeFlags.Boolean);
|
|
||||||
let union = type as UnionType;
|
|
||||||
if (assumeTrue) {
|
|
||||||
return getUnionType(filter(union.types, t => !!(t.flags & flags)));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return getUnionType(filter(union.types, t => !(t.flags & flags)));
|
assumeTrue = !assumeTrue;
|
||||||
|
flags = TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol | TypeFlags.Boolean;
|
||||||
}
|
}
|
||||||
|
// At this point we can bail if it's not a union
|
||||||
|
if (!(type.flags & TypeFlags.Union)) {
|
||||||
|
// If the active non-union type would be removed from a union by this type guard, return an empty union
|
||||||
|
return (assumeTrue === !!(type.flags & flags)) ? type : getUnionType(emptyArray);
|
||||||
|
}
|
||||||
|
return getUnionType(filter((type as UnionType).types, t => assumeTrue === !!(t.flags & flags)), /*noSubtypeReduction*/ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function narrowTypeByAnd(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
function narrowTypeByAnd(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||||
|
@ -12554,7 +12537,13 @@ namespace ts {
|
||||||
|
|
||||||
// After we remove all types that are StringLike, we will know if there was a string constituent
|
// After we remove all types that are StringLike, we will know if there was a string constituent
|
||||||
// based on whether the remaining type is the same as the initial type.
|
// based on whether the remaining type is the same as the initial type.
|
||||||
let arrayType = removeTypesFromUnionType(arrayOrStringType, TypeFlags.StringLike, /*isTypeOfKind*/ true, /*allowEmptyUnionResult*/ true);
|
let arrayType = arrayOrStringType;
|
||||||
|
if (arrayOrStringType.flags & TypeFlags.Union) {
|
||||||
|
arrayType = getUnionType(filter((arrayOrStringType as UnionType).types, t => !(t.flags & TypeFlags.StringLike)));
|
||||||
|
}
|
||||||
|
else if (arrayOrStringType.flags & TypeFlags.StringLike) {
|
||||||
|
arrayType = getUnionType(emptyArray);
|
||||||
|
}
|
||||||
let hasStringConstituent = arrayOrStringType !== arrayType;
|
let hasStringConstituent = arrayOrStringType !== arrayType;
|
||||||
|
|
||||||
let reportedError = false;
|
let reportedError = false;
|
||||||
|
|
41
tests/baselines/reference/typeGuardEnums.js
Normal file
41
tests/baselines/reference/typeGuardEnums.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//// [typeGuardEnums.ts]
|
||||||
|
enum E {}
|
||||||
|
enum V {}
|
||||||
|
|
||||||
|
let x: number|string|E|V;
|
||||||
|
|
||||||
|
if (typeof x === "number") {
|
||||||
|
x; // number|E|V
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // string
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof x !== "number") {
|
||||||
|
x; // string
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // number|E|V
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [typeGuardEnums.js]
|
||||||
|
var E;
|
||||||
|
(function (E) {
|
||||||
|
})(E || (E = {}));
|
||||||
|
var V;
|
||||||
|
(function (V) {
|
||||||
|
})(V || (V = {}));
|
||||||
|
var x;
|
||||||
|
if (typeof x === "number") {
|
||||||
|
x; // number|E|V
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // string
|
||||||
|
}
|
||||||
|
if (typeof x !== "number") {
|
||||||
|
x; // string
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // number|E|V
|
||||||
|
}
|
34
tests/baselines/reference/typeGuardEnums.symbols
Normal file
34
tests/baselines/reference/typeGuardEnums.symbols
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardEnums.ts ===
|
||||||
|
enum E {}
|
||||||
|
>E : Symbol(E, Decl(typeGuardEnums.ts, 0, 0))
|
||||||
|
|
||||||
|
enum V {}
|
||||||
|
>V : Symbol(V, Decl(typeGuardEnums.ts, 0, 9))
|
||||||
|
|
||||||
|
let x: number|string|E|V;
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
>E : Symbol(E, Decl(typeGuardEnums.ts, 0, 0))
|
||||||
|
>V : Symbol(V, Decl(typeGuardEnums.ts, 0, 9))
|
||||||
|
|
||||||
|
if (typeof x === "number") {
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
|
||||||
|
x; // number|E|V
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // string
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof x !== "number") {
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
|
||||||
|
x; // string
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // number|E|V
|
||||||
|
>x : Symbol(x, Decl(typeGuardEnums.ts, 3, 3))
|
||||||
|
}
|
||||||
|
|
40
tests/baselines/reference/typeGuardEnums.types
Normal file
40
tests/baselines/reference/typeGuardEnums.types
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardEnums.ts ===
|
||||||
|
enum E {}
|
||||||
|
>E : E
|
||||||
|
|
||||||
|
enum V {}
|
||||||
|
>V : V
|
||||||
|
|
||||||
|
let x: number|string|E|V;
|
||||||
|
>x : number | string | E | V
|
||||||
|
>E : E
|
||||||
|
>V : V
|
||||||
|
|
||||||
|
if (typeof x === "number") {
|
||||||
|
>typeof x === "number" : boolean
|
||||||
|
>typeof x : string
|
||||||
|
>x : number | string | E | V
|
||||||
|
>"number" : string
|
||||||
|
|
||||||
|
x; // number|E|V
|
||||||
|
>x : number | E | V
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // string
|
||||||
|
>x : string
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof x !== "number") {
|
||||||
|
>typeof x !== "number" : boolean
|
||||||
|
>typeof x : string
|
||||||
|
>x : number | string | E | V
|
||||||
|
>"number" : string
|
||||||
|
|
||||||
|
x; // string
|
||||||
|
>x : string
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // number|E|V
|
||||||
|
>x : number | E | V
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,31 @@
|
||||||
//// [typeGuardNesting.ts]
|
//// [typeGuardNesting.ts]
|
||||||
let strOrBool: string|boolean;
|
let strOrBool: string|boolean;
|
||||||
if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'string') {
|
if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'string') {
|
||||||
var label: string = (typeof strOrBool === 'string') ? strOrBool : "other string";
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boolean') {
|
||||||
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//// [typeGuardNesting.js]
|
//// [typeGuardNesting.js]
|
||||||
var strOrBool;
|
var strOrBool;
|
||||||
if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'string') {
|
if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'string') {
|
||||||
var label = (typeof strOrBool === 'string') ? strOrBool : "other string";
|
var label = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
var bool = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
var label2 = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
var bool2 = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
}
|
||||||
|
if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boolean') {
|
||||||
|
var label = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
var bool = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
var label2 = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
var bool2 = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,50 @@ if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'stri
|
||||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
var label: string = (typeof strOrBool === 'string') ? strOrBool : "other string";
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
>label : Symbol(label, Decl(typeGuardNesting.ts, 2, 4))
|
>label : Symbol(label, Decl(typeGuardNesting.ts, 2, 4))
|
||||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
>bool : Symbol(bool, Decl(typeGuardNesting.ts, 3, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
>label2 : Symbol(label2, Decl(typeGuardNesting.ts, 4, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
>bool2 : Symbol(bool2, Decl(typeGuardNesting.ts, 5, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boolean') {
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
>label : Symbol(label, Decl(typeGuardNesting.ts, 9, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
>bool : Symbol(bool, Decl(typeGuardNesting.ts, 10, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
>label2 : Symbol(label2, Decl(typeGuardNesting.ts, 11, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
>bool2 : Symbol(bool2, Decl(typeGuardNesting.ts, 12, 4))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
>strOrBool : Symbol(strOrBool, Decl(typeGuardNesting.ts, 0, 3))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,108 @@ if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'stri
|
||||||
>strOrBool : string | boolean
|
>strOrBool : string | boolean
|
||||||
>'string' : string
|
>'string' : string
|
||||||
|
|
||||||
var label: string = (typeof strOrBool === 'string') ? strOrBool : "other string";
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
>label : string
|
>label : string
|
||||||
>(typeof strOrBool === 'string') ? strOrBool : "other string" : string
|
>(typeof strOrBool === 'string') ? strOrBool : "string" : string
|
||||||
>(typeof strOrBool === 'string') : boolean
|
>(typeof strOrBool === 'string') : boolean
|
||||||
>typeof strOrBool === 'string' : boolean
|
>typeof strOrBool === 'string' : boolean
|
||||||
>typeof strOrBool : string
|
>typeof strOrBool : string
|
||||||
>strOrBool : boolean | string
|
>strOrBool : boolean | string
|
||||||
>'string' : string
|
>'string' : string
|
||||||
>strOrBool : string
|
>strOrBool : string
|
||||||
>"other string" : string
|
>"string" : string
|
||||||
|
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
>bool : boolean
|
||||||
|
>(typeof strOrBool === 'boolean') ? strOrBool : false : boolean
|
||||||
|
>(typeof strOrBool === 'boolean') : boolean
|
||||||
|
>typeof strOrBool === 'boolean' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'boolean' : string
|
||||||
|
>strOrBool : boolean
|
||||||
|
>false : boolean
|
||||||
|
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
>label2 : string
|
||||||
|
>(typeof strOrBool !== 'boolean') ? strOrBool : "string" : string
|
||||||
|
>(typeof strOrBool !== 'boolean') : boolean
|
||||||
|
>typeof strOrBool !== 'boolean' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'boolean' : string
|
||||||
|
>strOrBool : string
|
||||||
|
>"string" : string
|
||||||
|
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
>bool2 : boolean
|
||||||
|
>(typeof strOrBool !== 'string') ? strOrBool : false : boolean
|
||||||
|
>(typeof strOrBool !== 'string') : boolean
|
||||||
|
>typeof strOrBool !== 'string' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'string' : string
|
||||||
|
>strOrBool : boolean
|
||||||
|
>false : boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boolean') {
|
||||||
|
>(typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boolean' : boolean
|
||||||
|
>(typeof strOrBool !== 'string' && !strOrBool) : boolean
|
||||||
|
>typeof strOrBool !== 'string' && !strOrBool : boolean
|
||||||
|
>typeof strOrBool !== 'string' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : string | boolean
|
||||||
|
>'string' : string
|
||||||
|
>!strOrBool : boolean
|
||||||
|
>strOrBool : boolean
|
||||||
|
>typeof strOrBool !== 'boolean' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : string | boolean
|
||||||
|
>'boolean' : string
|
||||||
|
|
||||||
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
>label : string
|
||||||
|
>(typeof strOrBool === 'string') ? strOrBool : "string" : string
|
||||||
|
>(typeof strOrBool === 'string') : boolean
|
||||||
|
>typeof strOrBool === 'string' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'string' : string
|
||||||
|
>strOrBool : string
|
||||||
|
>"string" : string
|
||||||
|
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
>bool : boolean
|
||||||
|
>(typeof strOrBool === 'boolean') ? strOrBool : false : boolean
|
||||||
|
>(typeof strOrBool === 'boolean') : boolean
|
||||||
|
>typeof strOrBool === 'boolean' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'boolean' : string
|
||||||
|
>strOrBool : boolean
|
||||||
|
>false : boolean
|
||||||
|
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
>label2 : string
|
||||||
|
>(typeof strOrBool !== 'boolean') ? strOrBool : "string" : string
|
||||||
|
>(typeof strOrBool !== 'boolean') : boolean
|
||||||
|
>typeof strOrBool !== 'boolean' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'boolean' : string
|
||||||
|
>strOrBool : string
|
||||||
|
>"string" : string
|
||||||
|
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
>bool2 : boolean
|
||||||
|
>(typeof strOrBool !== 'string') ? strOrBool : false : boolean
|
||||||
|
>(typeof strOrBool !== 'string') : boolean
|
||||||
|
>typeof strOrBool !== 'string' : boolean
|
||||||
|
>typeof strOrBool : string
|
||||||
|
>strOrBool : boolean | string
|
||||||
|
>'string' : string
|
||||||
|
>strOrBool : boolean
|
||||||
|
>false : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,19 +23,19 @@ if (typeof strOrC === "Object") {
|
||||||
c = strOrC; // C
|
c = strOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
}
|
}
|
||||||
if (typeof numOrC === "Object") {
|
if (typeof numOrC === "Object") {
|
||||||
c = numOrC; // C
|
c = numOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
}
|
}
|
||||||
if (typeof boolOrC === "Object") {
|
if (typeof boolOrC === "Object") {
|
||||||
c = boolOrC; // C
|
c = boolOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// Narrowing occurs only if target type is a subtype of variable type
|
// Narrowing occurs only if target type is a subtype of variable type
|
||||||
|
@ -50,19 +50,19 @@ else {
|
||||||
// - when true, narrows the type of x by typeof x === s when false, or
|
// - when true, narrows the type of x by typeof x === s when false, or
|
||||||
// - when false, narrows the type of x by typeof x === s when true.
|
// - when false, narrows the type of x by typeof x === s when true.
|
||||||
if (typeof strOrC !== "Object") {
|
if (typeof strOrC !== "Object") {
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = strOrC; // C
|
c = strOrC; // C
|
||||||
}
|
}
|
||||||
if (typeof numOrC !== "Object") {
|
if (typeof numOrC !== "Object") {
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = numOrC; // C
|
c = numOrC; // C
|
||||||
}
|
}
|
||||||
if (typeof boolOrC !== "Object") {
|
if (typeof boolOrC !== "Object") {
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = boolOrC; // C
|
c = boolOrC; // C
|
||||||
|
@ -104,19 +104,19 @@ if (typeof strOrC === "Object") {
|
||||||
c = strOrC; // C
|
c = strOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r2 = strOrC; // string | C
|
var r2 = strOrC; // string
|
||||||
}
|
}
|
||||||
if (typeof numOrC === "Object") {
|
if (typeof numOrC === "Object") {
|
||||||
c = numOrC; // C
|
c = numOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r3 = numOrC; // number | C
|
var r3 = numOrC; // number
|
||||||
}
|
}
|
||||||
if (typeof boolOrC === "Object") {
|
if (typeof boolOrC === "Object") {
|
||||||
c = boolOrC; // C
|
c = boolOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r4 = boolOrC; // boolean | C
|
var r4 = boolOrC; // boolean
|
||||||
}
|
}
|
||||||
// Narrowing occurs only if target type is a subtype of variable type
|
// Narrowing occurs only if target type is a subtype of variable type
|
||||||
if (typeof strOrNumOrBool === "Object") {
|
if (typeof strOrNumOrBool === "Object") {
|
||||||
|
@ -129,19 +129,19 @@ else {
|
||||||
// - when true, narrows the type of x by typeof x === s when false, or
|
// - when true, narrows the type of x by typeof x === s when false, or
|
||||||
// - when false, narrows the type of x by typeof x === s when true.
|
// - when false, narrows the type of x by typeof x === s when true.
|
||||||
if (typeof strOrC !== "Object") {
|
if (typeof strOrC !== "Object") {
|
||||||
var r2 = strOrC; // string | C
|
var r2 = strOrC; // string
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = strOrC; // C
|
c = strOrC; // C
|
||||||
}
|
}
|
||||||
if (typeof numOrC !== "Object") {
|
if (typeof numOrC !== "Object") {
|
||||||
var r3 = numOrC; // number | C
|
var r3 = numOrC; // number
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = numOrC; // C
|
c = numOrC; // C
|
||||||
}
|
}
|
||||||
if (typeof boolOrC !== "Object") {
|
if (typeof boolOrC !== "Object") {
|
||||||
var r4 = boolOrC; // boolean | C
|
var r4 = boolOrC; // boolean
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = boolOrC; // C
|
c = boolOrC; // C
|
||||||
|
|
|
@ -56,9 +56,8 @@ if (typeof strOrC === "Object") {
|
||||||
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
>r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 51, 7))
|
>r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 51, 7))
|
||||||
>C : Symbol(C, Decl(typeGuardOfFormTypeOfOther.ts, 0, 0))
|
|
||||||
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
||||||
}
|
}
|
||||||
if (typeof numOrC === "Object") {
|
if (typeof numOrC === "Object") {
|
||||||
|
@ -69,9 +68,8 @@ if (typeof numOrC === "Object") {
|
||||||
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
>r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 57, 7))
|
>r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 57, 7))
|
||||||
>C : Symbol(C, Decl(typeGuardOfFormTypeOfOther.ts, 0, 0))
|
|
||||||
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
||||||
}
|
}
|
||||||
if (typeof boolOrC === "Object") {
|
if (typeof boolOrC === "Object") {
|
||||||
|
@ -82,9 +80,8 @@ if (typeof boolOrC === "Object") {
|
||||||
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
>r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 63, 7))
|
>r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 63, 7))
|
||||||
>C : Symbol(C, Decl(typeGuardOfFormTypeOfOther.ts, 0, 0))
|
|
||||||
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,9 +105,8 @@ else {
|
||||||
if (typeof strOrC !== "Object") {
|
if (typeof strOrC !== "Object") {
|
||||||
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
||||||
|
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
>r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 51, 7))
|
>r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 51, 7))
|
||||||
>C : Symbol(C, Decl(typeGuardOfFormTypeOfOther.ts, 0, 0))
|
|
||||||
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
>strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -121,9 +117,8 @@ else {
|
||||||
if (typeof numOrC !== "Object") {
|
if (typeof numOrC !== "Object") {
|
||||||
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
||||||
|
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
>r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 57, 7))
|
>r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 57, 7))
|
||||||
>C : Symbol(C, Decl(typeGuardOfFormTypeOfOther.ts, 0, 0))
|
|
||||||
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
>numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -134,9 +129,8 @@ else {
|
||||||
if (typeof boolOrC !== "Object") {
|
if (typeof boolOrC !== "Object") {
|
||||||
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
||||||
|
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
>r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 63, 7))
|
>r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 63, 7))
|
||||||
>C : Symbol(C, Decl(typeGuardOfFormTypeOfOther.ts, 0, 0))
|
|
||||||
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
>boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -60,9 +60,8 @@ if (typeof strOrC === "Object") {
|
||||||
>strOrC : C
|
>strOrC : C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
>r2 : string | C
|
>r2 : string
|
||||||
>C : C
|
|
||||||
>strOrC : string
|
>strOrC : string
|
||||||
}
|
}
|
||||||
if (typeof numOrC === "Object") {
|
if (typeof numOrC === "Object") {
|
||||||
|
@ -77,9 +76,8 @@ if (typeof numOrC === "Object") {
|
||||||
>numOrC : C
|
>numOrC : C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
>r3 : number | C
|
>r3 : number
|
||||||
>C : C
|
|
||||||
>numOrC : number
|
>numOrC : number
|
||||||
}
|
}
|
||||||
if (typeof boolOrC === "Object") {
|
if (typeof boolOrC === "Object") {
|
||||||
|
@ -94,9 +92,8 @@ if (typeof boolOrC === "Object") {
|
||||||
>boolOrC : C
|
>boolOrC : C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
>r4 : boolean | C
|
>r4 : boolean
|
||||||
>C : C
|
|
||||||
>boolOrC : boolean
|
>boolOrC : boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +123,8 @@ if (typeof strOrC !== "Object") {
|
||||||
>strOrC : string | C
|
>strOrC : string | C
|
||||||
>"Object" : string
|
>"Object" : string
|
||||||
|
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
>r2 : string | C
|
>r2 : string
|
||||||
>C : C
|
|
||||||
>strOrC : string
|
>strOrC : string
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -143,9 +139,8 @@ if (typeof numOrC !== "Object") {
|
||||||
>numOrC : number | C
|
>numOrC : number | C
|
||||||
>"Object" : string
|
>"Object" : string
|
||||||
|
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
>r3 : number | C
|
>r3 : number
|
||||||
>C : C
|
|
||||||
>numOrC : number
|
>numOrC : number
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -160,9 +155,8 @@ if (typeof boolOrC !== "Object") {
|
||||||
>boolOrC : boolean | C
|
>boolOrC : boolean | C
|
||||||
>"Object" : string
|
>"Object" : string
|
||||||
|
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
>r4 : boolean | C
|
>r4 : boolean
|
||||||
>C : C
|
|
||||||
>boolOrC : boolean
|
>boolOrC : boolean
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//// [typeGuardTautologicalConsistiency.ts]
|
||||||
|
let stringOrNumber: string | number;
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number") {
|
||||||
|
if (typeof stringOrNumber !== "number") {
|
||||||
|
stringOrNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") {
|
||||||
|
stringOrNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [typeGuardTautologicalConsistiency.js]
|
||||||
|
var stringOrNumber;
|
||||||
|
if (typeof stringOrNumber === "number") {
|
||||||
|
if (typeof stringOrNumber !== "number") {
|
||||||
|
stringOrNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") {
|
||||||
|
stringOrNumber;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardTautologicalConsistiency.ts ===
|
||||||
|
let stringOrNumber: string | number;
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number") {
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
|
||||||
|
if (typeof stringOrNumber !== "number") {
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
|
||||||
|
stringOrNumber;
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") {
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
|
||||||
|
stringOrNumber;
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(typeGuardTautologicalConsistiency.ts, 0, 3))
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardTautologicalConsistiency.ts ===
|
||||||
|
let stringOrNumber: string | number;
|
||||||
|
>stringOrNumber : string | number
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number") {
|
||||||
|
>typeof stringOrNumber === "number" : boolean
|
||||||
|
>typeof stringOrNumber : string
|
||||||
|
>stringOrNumber : string | number
|
||||||
|
>"number" : string
|
||||||
|
|
||||||
|
if (typeof stringOrNumber !== "number") {
|
||||||
|
>typeof stringOrNumber !== "number" : boolean
|
||||||
|
>typeof stringOrNumber : string
|
||||||
|
>stringOrNumber : number
|
||||||
|
>"number" : string
|
||||||
|
|
||||||
|
stringOrNumber;
|
||||||
|
>stringOrNumber : string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") {
|
||||||
|
>typeof stringOrNumber === "number" && typeof stringOrNumber !== "number" : boolean
|
||||||
|
>typeof stringOrNumber === "number" : boolean
|
||||||
|
>typeof stringOrNumber : string
|
||||||
|
>stringOrNumber : string | number
|
||||||
|
>"number" : string
|
||||||
|
>typeof stringOrNumber !== "number" : boolean
|
||||||
|
>typeof stringOrNumber : string
|
||||||
|
>stringOrNumber : number
|
||||||
|
>"number" : string
|
||||||
|
|
||||||
|
stringOrNumber;
|
||||||
|
>stringOrNumber : number
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
enum E {}
|
||||||
|
enum V {}
|
||||||
|
|
||||||
|
let x: number|string|E|V;
|
||||||
|
|
||||||
|
if (typeof x === "number") {
|
||||||
|
x; // number|E|V
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // string
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof x !== "number") {
|
||||||
|
x; // string
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x; // number|E|V
|
||||||
|
}
|
|
@ -1,4 +1,14 @@
|
||||||
let strOrBool: string|boolean;
|
let strOrBool: string|boolean;
|
||||||
if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'string') {
|
if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'string') {
|
||||||
var label: string = (typeof strOrBool === 'string') ? strOrBool : "other string";
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boolean') {
|
||||||
|
let label: string = (typeof strOrBool === 'string') ? strOrBool : "string";
|
||||||
|
let bool: boolean = (typeof strOrBool === 'boolean') ? strOrBool : false;
|
||||||
|
let label2: string = (typeof strOrBool !== 'boolean') ? strOrBool : "string";
|
||||||
|
let bool2: boolean = (typeof strOrBool !== 'string') ? strOrBool : false;
|
||||||
}
|
}
|
|
@ -22,19 +22,19 @@ if (typeof strOrC === "Object") {
|
||||||
c = strOrC; // C
|
c = strOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
}
|
}
|
||||||
if (typeof numOrC === "Object") {
|
if (typeof numOrC === "Object") {
|
||||||
c = numOrC; // C
|
c = numOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
}
|
}
|
||||||
if (typeof boolOrC === "Object") {
|
if (typeof boolOrC === "Object") {
|
||||||
c = boolOrC; // C
|
c = boolOrC; // C
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// Narrowing occurs only if target type is a subtype of variable type
|
// Narrowing occurs only if target type is a subtype of variable type
|
||||||
|
@ -49,19 +49,19 @@ else {
|
||||||
// - when true, narrows the type of x by typeof x === s when false, or
|
// - when true, narrows the type of x by typeof x === s when false, or
|
||||||
// - when false, narrows the type of x by typeof x === s when true.
|
// - when false, narrows the type of x by typeof x === s when true.
|
||||||
if (typeof strOrC !== "Object") {
|
if (typeof strOrC !== "Object") {
|
||||||
var r2: string | C = strOrC; // string | C
|
var r2: string = strOrC; // string
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = strOrC; // C
|
c = strOrC; // C
|
||||||
}
|
}
|
||||||
if (typeof numOrC !== "Object") {
|
if (typeof numOrC !== "Object") {
|
||||||
var r3: number | C = numOrC; // number | C
|
var r3: number = numOrC; // number
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = numOrC; // C
|
c = numOrC; // C
|
||||||
}
|
}
|
||||||
if (typeof boolOrC !== "Object") {
|
if (typeof boolOrC !== "Object") {
|
||||||
var r4: boolean | C = boolOrC; // boolean | C
|
var r4: boolean = boolOrC; // boolean
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = boolOrC; // C
|
c = boolOrC; // C
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
let stringOrNumber: string | number;
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number") {
|
||||||
|
if (typeof stringOrNumber !== "number") {
|
||||||
|
stringOrNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") {
|
||||||
|
stringOrNumber;
|
||||||
|
}
|
Loading…
Reference in a new issue