Merge pull request #9036 from Microsoft/primitive-type-guards-are-order-independent
Primitive type guards are order independent
This commit is contained in:
commit
8b093128b3
|
@ -610,10 +610,11 @@ namespace ts {
|
|||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsEqualsToken:
|
||||
if (isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) {
|
||||
if ((isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) ||
|
||||
(isNarrowingExpression(expr.right) && (expr.left.kind === SyntaxKind.NullKeyword || expr.left.kind === SyntaxKind.Identifier))) {
|
||||
return true;
|
||||
}
|
||||
if (expr.left.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((<TypeOfExpression>expr.left).expression) && expr.right.kind === SyntaxKind.StringLiteral) {
|
||||
if (isTypeOfNarrowingBinaryExpression(expr)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -625,6 +626,20 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function isTypeOfNarrowingBinaryExpression(expr: BinaryExpression) {
|
||||
let typeOf: Expression;
|
||||
if (expr.left.kind === SyntaxKind.StringLiteral) {
|
||||
typeOf = expr.right;
|
||||
}
|
||||
else if (expr.right.kind === SyntaxKind.StringLiteral) {
|
||||
typeOf = expr.left;
|
||||
}
|
||||
else {
|
||||
typeOf = undefined;
|
||||
}
|
||||
return typeOf && typeOf.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((<TypeOfExpression>typeOf).expression);
|
||||
}
|
||||
|
||||
function createBranchLabel(): FlowLabel {
|
||||
return {
|
||||
flags: FlowFlags.BranchLabel,
|
||||
|
|
|
@ -7895,10 +7895,11 @@ namespace ts {
|
|||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsEqualsToken:
|
||||
if (isNullOrUndefinedLiteral(expr.right)) {
|
||||
if (isNullOrUndefinedLiteral(expr.left) || isNullOrUndefinedLiteral(expr.right)) {
|
||||
return narrowTypeByNullCheck(type, expr, assumeTrue);
|
||||
}
|
||||
if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral) {
|
||||
if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral ||
|
||||
expr.left.kind === SyntaxKind.StringLiteral && expr.right.kind === SyntaxKind.TypeOfExpression) {
|
||||
return narrowTypeByTypeof(type, expr, assumeTrue);
|
||||
}
|
||||
break;
|
||||
|
@ -7911,18 +7912,20 @@ namespace ts {
|
|||
}
|
||||
|
||||
function narrowTypeByNullCheck(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||
// We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' on the right
|
||||
// We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' on one side
|
||||
const operator = expr.operatorToken.kind;
|
||||
const nullLike = isNullOrUndefinedLiteral(expr.left) ? expr.left : expr.right;
|
||||
const narrowed = isNullOrUndefinedLiteral(expr.left) ? expr.right : expr.left;
|
||||
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(expr.left))) {
|
||||
if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(narrowed))) {
|
||||
return type;
|
||||
}
|
||||
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
|
||||
const facts = doubleEquals ?
|
||||
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
|
||||
expr.right.kind === SyntaxKind.NullKeyword ?
|
||||
nullLike.kind === SyntaxKind.NullKeyword ?
|
||||
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
|
||||
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
|
||||
return getTypeWithFacts(type, facts);
|
||||
|
@ -7931,12 +7934,12 @@ namespace ts {
|
|||
function narrowTypeByTypeof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||
// We have '==', '!=', '====', or !==' operator with 'typeof xxx' on the left
|
||||
// and string literal on the right
|
||||
const left = getReferenceFromExpression((<TypeOfExpression>expr.left).expression);
|
||||
const right = <LiteralExpression>expr.right;
|
||||
if (!isMatchingReference(reference, left)) {
|
||||
const narrowed = getReferenceFromExpression((<TypeOfExpression>(expr.left.kind === SyntaxKind.TypeOfExpression ? expr.left : expr.right)).expression);
|
||||
const literal = <LiteralExpression>(expr.right.kind === SyntaxKind.StringLiteral ? expr.right : expr.left);
|
||||
if (!isMatchingReference(reference, narrowed)) {
|
||||
// For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
|
||||
// narrowed type of 'y' to its declared type.
|
||||
if (containsMatchingReference(reference, left)) {
|
||||
if (containsMatchingReference(reference, narrowed)) {
|
||||
return declaredType;
|
||||
}
|
||||
return type;
|
||||
|
@ -7949,14 +7952,14 @@ namespace ts {
|
|||
// We narrow a non-union type to an exact primitive type if the non-union type
|
||||
// is a supertype of that primtive type. For example, type 'any' can be narrowed
|
||||
// to one of the primitive types.
|
||||
const targetType = getProperty(typeofTypesByName, right.text);
|
||||
const targetType = getProperty(typeofTypesByName, literal.text);
|
||||
if (targetType && isTypeSubtypeOf(targetType, type)) {
|
||||
return targetType;
|
||||
}
|
||||
}
|
||||
const facts = assumeTrue ?
|
||||
getProperty(typeofEQFacts, right.text) || TypeFacts.TypeofEQHostObject :
|
||||
getProperty(typeofNEFacts, right.text) || TypeFacts.TypeofNEHostObject;
|
||||
getProperty(typeofEQFacts, literal.text) || TypeFacts.TypeofEQHostObject :
|
||||
getProperty(typeofNEFacts, literal.text) || TypeFacts.TypeofNEHostObject;
|
||||
return getTypeWithFacts(type, facts);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//// [nullOrUndefinedTypeGuardIsOrderIndependent.ts]
|
||||
function test(strOrNull: string | null, strOrUndefined: string | undefined) {
|
||||
var str: string = "original";
|
||||
var nil: null;
|
||||
if (null === strOrNull) {
|
||||
nil = strOrNull;
|
||||
}
|
||||
else {
|
||||
str = strOrNull;
|
||||
}
|
||||
if (undefined !== strOrUndefined) {
|
||||
str = strOrUndefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [nullOrUndefinedTypeGuardIsOrderIndependent.js]
|
||||
function test(strOrNull, strOrUndefined) {
|
||||
var str = "original";
|
||||
var nil;
|
||||
if (null === strOrNull) {
|
||||
nil = strOrNull;
|
||||
}
|
||||
else {
|
||||
str = strOrNull;
|
||||
}
|
||||
if (undefined !== strOrUndefined) {
|
||||
str = strOrUndefined;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
=== tests/cases/conformance/expressions/typeGuards/nullOrUndefinedTypeGuardIsOrderIndependent.ts ===
|
||||
function test(strOrNull: string | null, strOrUndefined: string | undefined) {
|
||||
>test : Symbol(test, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 0))
|
||||
>strOrNull : Symbol(strOrNull, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 14))
|
||||
>strOrUndefined : Symbol(strOrUndefined, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 39))
|
||||
|
||||
var str: string = "original";
|
||||
>str : Symbol(str, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 1, 7))
|
||||
|
||||
var nil: null;
|
||||
>nil : Symbol(nil, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 2, 7))
|
||||
|
||||
if (null === strOrNull) {
|
||||
>strOrNull : Symbol(strOrNull, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 14))
|
||||
|
||||
nil = strOrNull;
|
||||
>nil : Symbol(nil, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 2, 7))
|
||||
>strOrNull : Symbol(strOrNull, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 14))
|
||||
}
|
||||
else {
|
||||
str = strOrNull;
|
||||
>str : Symbol(str, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 1, 7))
|
||||
>strOrNull : Symbol(strOrNull, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 14))
|
||||
}
|
||||
if (undefined !== strOrUndefined) {
|
||||
>undefined : Symbol(undefined)
|
||||
>strOrUndefined : Symbol(strOrUndefined, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 39))
|
||||
|
||||
str = strOrUndefined;
|
||||
>str : Symbol(str, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 1, 7))
|
||||
>strOrUndefined : Symbol(strOrUndefined, Decl(nullOrUndefinedTypeGuardIsOrderIndependent.ts, 0, 39))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
=== tests/cases/conformance/expressions/typeGuards/nullOrUndefinedTypeGuardIsOrderIndependent.ts ===
|
||||
function test(strOrNull: string | null, strOrUndefined: string | undefined) {
|
||||
>test : (strOrNull: string | null, strOrUndefined: string | undefined) => void
|
||||
>strOrNull : string | null
|
||||
>null : null
|
||||
>strOrUndefined : string | undefined
|
||||
|
||||
var str: string = "original";
|
||||
>str : string
|
||||
>"original" : string
|
||||
|
||||
var nil: null;
|
||||
>nil : null
|
||||
>null : null
|
||||
|
||||
if (null === strOrNull) {
|
||||
>null === strOrNull : boolean
|
||||
>null : null
|
||||
>strOrNull : string | null
|
||||
|
||||
nil = strOrNull;
|
||||
>nil = strOrNull : null
|
||||
>nil : null
|
||||
>strOrNull : null
|
||||
}
|
||||
else {
|
||||
str = strOrNull;
|
||||
>str = strOrNull : string
|
||||
>str : string
|
||||
>strOrNull : string
|
||||
}
|
||||
if (undefined !== strOrUndefined) {
|
||||
>undefined !== strOrUndefined : boolean
|
||||
>undefined : undefined
|
||||
>strOrUndefined : string | undefined
|
||||
|
||||
str = strOrUndefined;
|
||||
>str = strOrUndefined : string
|
||||
>str : string
|
||||
>strOrUndefined : string
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
//// [typeGuardOfFormTypeOfIsOrderIndependent.ts]
|
||||
var strOrNum: string | number;
|
||||
var strOrBool: string | boolean;
|
||||
var strOrFunc: string | (() => void);
|
||||
var numOrBool: number | boolean
|
||||
var str: string;
|
||||
var num: number;
|
||||
var bool: boolean;
|
||||
var func: () => void;
|
||||
|
||||
if ("string" === typeof strOrNum) {
|
||||
str = strOrNum;
|
||||
}
|
||||
else {
|
||||
num = strOrNum;
|
||||
}
|
||||
if ("function" === typeof strOrFunc) {
|
||||
func = strOrFunc;
|
||||
}
|
||||
else {
|
||||
str = strOrFunc;
|
||||
}
|
||||
if ("number" === typeof numOrBool) {
|
||||
num = numOrBool;
|
||||
}
|
||||
else {
|
||||
bool = numOrBool;
|
||||
}
|
||||
if ("boolean" === typeof strOrBool) {
|
||||
bool = strOrBool;
|
||||
}
|
||||
else {
|
||||
str = strOrBool;
|
||||
}
|
||||
|
||||
|
||||
//// [typeGuardOfFormTypeOfIsOrderIndependent.js]
|
||||
var strOrNum;
|
||||
var strOrBool;
|
||||
var strOrFunc;
|
||||
var numOrBool;
|
||||
var str;
|
||||
var num;
|
||||
var bool;
|
||||
var func;
|
||||
if ("string" === typeof strOrNum) {
|
||||
str = strOrNum;
|
||||
}
|
||||
else {
|
||||
num = strOrNum;
|
||||
}
|
||||
if ("function" === typeof strOrFunc) {
|
||||
func = strOrFunc;
|
||||
}
|
||||
else {
|
||||
str = strOrFunc;
|
||||
}
|
||||
if ("number" === typeof numOrBool) {
|
||||
num = numOrBool;
|
||||
}
|
||||
else {
|
||||
bool = numOrBool;
|
||||
}
|
||||
if ("boolean" === typeof strOrBool) {
|
||||
bool = strOrBool;
|
||||
}
|
||||
else {
|
||||
str = strOrBool;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfIsOrderIndependent.ts ===
|
||||
var strOrNum: string | number;
|
||||
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 0, 3))
|
||||
|
||||
var strOrBool: string | boolean;
|
||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 1, 3))
|
||||
|
||||
var strOrFunc: string | (() => void);
|
||||
>strOrFunc : Symbol(strOrFunc, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 2, 3))
|
||||
|
||||
var numOrBool: number | boolean
|
||||
>numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 3, 3))
|
||||
|
||||
var str: string;
|
||||
>str : Symbol(str, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 4, 3))
|
||||
|
||||
var num: number;
|
||||
>num : Symbol(num, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 5, 3))
|
||||
|
||||
var bool: boolean;
|
||||
>bool : Symbol(bool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 6, 3))
|
||||
|
||||
var func: () => void;
|
||||
>func : Symbol(func, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 7, 3))
|
||||
|
||||
if ("string" === typeof strOrNum) {
|
||||
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 0, 3))
|
||||
|
||||
str = strOrNum;
|
||||
>str : Symbol(str, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 4, 3))
|
||||
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 0, 3))
|
||||
}
|
||||
else {
|
||||
num = strOrNum;
|
||||
>num : Symbol(num, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 5, 3))
|
||||
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 0, 3))
|
||||
}
|
||||
if ("function" === typeof strOrFunc) {
|
||||
>strOrFunc : Symbol(strOrFunc, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 2, 3))
|
||||
|
||||
func = strOrFunc;
|
||||
>func : Symbol(func, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 7, 3))
|
||||
>strOrFunc : Symbol(strOrFunc, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 2, 3))
|
||||
}
|
||||
else {
|
||||
str = strOrFunc;
|
||||
>str : Symbol(str, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 4, 3))
|
||||
>strOrFunc : Symbol(strOrFunc, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 2, 3))
|
||||
}
|
||||
if ("number" === typeof numOrBool) {
|
||||
>numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 3, 3))
|
||||
|
||||
num = numOrBool;
|
||||
>num : Symbol(num, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 5, 3))
|
||||
>numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 3, 3))
|
||||
}
|
||||
else {
|
||||
bool = numOrBool;
|
||||
>bool : Symbol(bool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 6, 3))
|
||||
>numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 3, 3))
|
||||
}
|
||||
if ("boolean" === typeof strOrBool) {
|
||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 1, 3))
|
||||
|
||||
bool = strOrBool;
|
||||
>bool : Symbol(bool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 6, 3))
|
||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 1, 3))
|
||||
}
|
||||
else {
|
||||
str = strOrBool;
|
||||
>str : Symbol(str, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 4, 3))
|
||||
>strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfIsOrderIndependent.ts, 1, 3))
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfIsOrderIndependent.ts ===
|
||||
var strOrNum: string | number;
|
||||
>strOrNum : string | number
|
||||
|
||||
var strOrBool: string | boolean;
|
||||
>strOrBool : string | boolean
|
||||
|
||||
var strOrFunc: string | (() => void);
|
||||
>strOrFunc : string | (() => void)
|
||||
|
||||
var numOrBool: number | boolean
|
||||
>numOrBool : number | boolean
|
||||
|
||||
var str: string;
|
||||
>str : string
|
||||
|
||||
var num: number;
|
||||
>num : number
|
||||
|
||||
var bool: boolean;
|
||||
>bool : boolean
|
||||
|
||||
var func: () => void;
|
||||
>func : () => void
|
||||
|
||||
if ("string" === typeof strOrNum) {
|
||||
>"string" === typeof strOrNum : boolean
|
||||
>"string" : string
|
||||
>typeof strOrNum : string
|
||||
>strOrNum : string | number
|
||||
|
||||
str = strOrNum;
|
||||
>str = strOrNum : string
|
||||
>str : string
|
||||
>strOrNum : string
|
||||
}
|
||||
else {
|
||||
num = strOrNum;
|
||||
>num = strOrNum : number
|
||||
>num : number
|
||||
>strOrNum : number
|
||||
}
|
||||
if ("function" === typeof strOrFunc) {
|
||||
>"function" === typeof strOrFunc : boolean
|
||||
>"function" : string
|
||||
>typeof strOrFunc : string
|
||||
>strOrFunc : string | (() => void)
|
||||
|
||||
func = strOrFunc;
|
||||
>func = strOrFunc : () => void
|
||||
>func : () => void
|
||||
>strOrFunc : () => void
|
||||
}
|
||||
else {
|
||||
str = strOrFunc;
|
||||
>str = strOrFunc : string
|
||||
>str : string
|
||||
>strOrFunc : string
|
||||
}
|
||||
if ("number" === typeof numOrBool) {
|
||||
>"number" === typeof numOrBool : boolean
|
||||
>"number" : string
|
||||
>typeof numOrBool : string
|
||||
>numOrBool : number | boolean
|
||||
|
||||
num = numOrBool;
|
||||
>num = numOrBool : number
|
||||
>num : number
|
||||
>numOrBool : number
|
||||
}
|
||||
else {
|
||||
bool = numOrBool;
|
||||
>bool = numOrBool : boolean
|
||||
>bool : boolean
|
||||
>numOrBool : boolean
|
||||
}
|
||||
if ("boolean" === typeof strOrBool) {
|
||||
>"boolean" === typeof strOrBool : boolean
|
||||
>"boolean" : string
|
||||
>typeof strOrBool : string
|
||||
>strOrBool : string | boolean
|
||||
|
||||
bool = strOrBool;
|
||||
>bool = strOrBool : boolean
|
||||
>bool : boolean
|
||||
>strOrBool : boolean
|
||||
}
|
||||
else {
|
||||
str = strOrBool;
|
||||
>str = strOrBool : string
|
||||
>str : string
|
||||
>strOrBool : string
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// @strictNullChecks: true
|
||||
function test(strOrNull: string | null, strOrUndefined: string | undefined) {
|
||||
var str: string = "original";
|
||||
var nil: null;
|
||||
if (null === strOrNull) {
|
||||
nil = strOrNull;
|
||||
}
|
||||
else {
|
||||
str = strOrNull;
|
||||
}
|
||||
if (undefined !== strOrUndefined) {
|
||||
str = strOrUndefined;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
var strOrNum: string | number;
|
||||
var strOrBool: string | boolean;
|
||||
var strOrFunc: string | (() => void);
|
||||
var numOrBool: number | boolean
|
||||
var str: string;
|
||||
var num: number;
|
||||
var bool: boolean;
|
||||
var func: () => void;
|
||||
|
||||
if ("string" === typeof strOrNum) {
|
||||
str = strOrNum;
|
||||
}
|
||||
else {
|
||||
num = strOrNum;
|
||||
}
|
||||
if ("function" === typeof strOrFunc) {
|
||||
func = strOrFunc;
|
||||
}
|
||||
else {
|
||||
str = strOrFunc;
|
||||
}
|
||||
if ("number" === typeof numOrBool) {
|
||||
num = numOrBool;
|
||||
}
|
||||
else {
|
||||
bool = numOrBool;
|
||||
}
|
||||
if ("boolean" === typeof strOrBool) {
|
||||
bool = strOrBool;
|
||||
}
|
||||
else {
|
||||
str = strOrBool;
|
||||
}
|
Loading…
Reference in a new issue