Preserve newlines for conditional expressions

This commit is contained in:
Cyrus Najmabadi
2015-03-07 13:50:26 -08:00
parent dddc4660a1
commit 2a990a8685
41 changed files with 485 additions and 90 deletions
+46 -5
View File
@@ -3330,10 +3330,45 @@ module ts {
function emitConditionalExpression(node: ConditionalExpression) {
emit(node.condition);
write(" ? ");
var indent1 = indentIfOnDifferentLines(node, node.condition, node.questionToken);
if (!indent1) {
write(" ");
}
write("?");
if (!indent1) {
var indent2 = indentIfOnDifferentLines(node, node.questionToken, node.whenTrue);
}
if (!indent2) {
write(" ");
}
emit(node.whenTrue);
write(" : ");
if (indent1 || indent2) {
decreaseIndent();
}
var indent3 = indentIfOnDifferentLines(node, node.whenTrue, node.colonToken);
if (!indent3) {
write(" ");
}
write(":");
if (!indent3) {
var indent4 = indentIfOnDifferentLines(node, node.colonToken, node.whenFalse);
}
if (!indent4) {
write(" ");
}
emit(node.whenFalse);
if (indent3 || indent4) {
decreaseIndent();
}
}
function isSingleLineEmptyBlock(node: Node) {
@@ -3706,10 +3741,16 @@ module ts {
equals.left = value;
equals.operatorToken = createSynthesizedNode(SyntaxKind.EqualsEqualsEqualsToken);
equals.right = createVoidZero();
return createConditionalExpression(equals, defaultValue, value);
}
function createConditionalExpression(condition: Expression, whenTrue: Expression, whenFalse: Expression) {
var cond = <ConditionalExpression>createSynthesizedNode(SyntaxKind.ConditionalExpression);
cond.condition = equals;
cond.whenTrue = defaultValue;
cond.whenFalse = value;
cond.condition = condition;
cond.questionToken = createSynthesizedNode(SyntaxKind.QuestionToken);
cond.whenTrue = whenTrue;
cond.colonToken = createSynthesizedNode(SyntaxKind.ColonToken);
cond.whenFalse = whenFalse;
return cond;
}
@@ -2034,7 +2034,8 @@ function transform(contents, compilerOptions) {
// Create a compilerHost object to allow the compiler to read and write files
var compilerHost = {
getSourceFile: function (fileName, target) {
return files[fileName] !== undefined ? ts.createSourceFile(fileName, files[fileName], target) : undefined;
return files[fileName] !== undefined ?
ts.createSourceFile(fileName, files[fileName], target) : undefined;
},
writeFile: function (name, text, writeByteOrderMark) {
outputs.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark });
@@ -0,0 +1,13 @@
tests/cases/compiler/conditionalExpressionNewLine1.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine1.ts(1,13): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine1.ts(1,17): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine1.ts (3 errors) ====
var v = a ? b : c;
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,5 @@
//// [conditionalExpressionNewLine1.ts]
var v = a ? b : c;
//// [conditionalExpressionNewLine1.js]
var v = a ? b : c;
@@ -0,0 +1,31 @@
tests/cases/compiler/conditionalExpressionNewLine10.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine10.ts(2,5): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine10.ts(3,7): error TS2304: Cannot find name 'd'.
tests/cases/compiler/conditionalExpressionNewLine10.ts(4,7): error TS2304: Cannot find name 'e'.
tests/cases/compiler/conditionalExpressionNewLine10.ts(5,5): error TS2304: Cannot find name 'c'.
tests/cases/compiler/conditionalExpressionNewLine10.ts(6,7): error TS2304: Cannot find name 'f'.
tests/cases/compiler/conditionalExpressionNewLine10.ts(7,7): error TS2304: Cannot find name 'g'.
==== tests/cases/compiler/conditionalExpressionNewLine10.ts (7 errors) ====
var v = a
~
!!! error TS2304: Cannot find name 'a'.
? b
~
!!! error TS2304: Cannot find name 'b'.
? d
~
!!! error TS2304: Cannot find name 'd'.
: e
~
!!! error TS2304: Cannot find name 'e'.
: c
~
!!! error TS2304: Cannot find name 'c'.
? f
~
!!! error TS2304: Cannot find name 'f'.
: g;
~
!!! error TS2304: Cannot find name 'g'.
@@ -0,0 +1,17 @@
//// [conditionalExpressionNewLine10.ts]
var v = a
? b
? d
: e
: c
? f
: g;
//// [conditionalExpressionNewLine10.js]
var v = a
? b
? d
: e
: c
? f
: g;
@@ -0,0 +1,14 @@
tests/cases/compiler/conditionalExpressionNewLine2.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine2.ts(2,5): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine2.ts(2,9): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine2.ts (3 errors) ====
var v = a
~
!!! error TS2304: Cannot find name 'a'.
? b : c;
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,7 @@
//// [conditionalExpressionNewLine2.ts]
var v = a
? b : c;
//// [conditionalExpressionNewLine2.js]
var v = a
? b : c;
@@ -0,0 +1,14 @@
tests/cases/compiler/conditionalExpressionNewLine3.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine3.ts(2,3): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine3.ts(2,7): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine3.ts (3 errors) ====
var v = a ?
~
!!! error TS2304: Cannot find name 'a'.
b : c;
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,7 @@
//// [conditionalExpressionNewLine3.ts]
var v = a ?
b : c;
//// [conditionalExpressionNewLine3.js]
var v = a ?
b : c;
@@ -0,0 +1,14 @@
tests/cases/compiler/conditionalExpressionNewLine4.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine4.ts(1,13): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine4.ts(2,3): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine4.ts (3 errors) ====
var v = a ? b :
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS2304: Cannot find name 'b'.
c;
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,7 @@
//// [conditionalExpressionNewLine4.ts]
var v = a ? b :
c;
//// [conditionalExpressionNewLine4.js]
var v = a ? b :
c;
@@ -0,0 +1,14 @@
tests/cases/compiler/conditionalExpressionNewLine5.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine5.ts(1,13): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine5.ts(2,5): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine5.ts (3 errors) ====
var v = a ? b
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS2304: Cannot find name 'b'.
: c;
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,7 @@
//// [conditionalExpressionNewLine5.ts]
var v = a ? b
: c;
//// [conditionalExpressionNewLine5.js]
var v = a ? b
: c;
@@ -0,0 +1,15 @@
tests/cases/compiler/conditionalExpressionNewLine6.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine6.ts(2,5): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine6.ts(3,5): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine6.ts (3 errors) ====
var v = a
~
!!! error TS2304: Cannot find name 'a'.
? b
~
!!! error TS2304: Cannot find name 'b'.
: c;
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,9 @@
//// [conditionalExpressionNewLine6.ts]
var v = a
? b
: c;
//// [conditionalExpressionNewLine6.js]
var v = a
? b
: c;
@@ -0,0 +1,15 @@
tests/cases/compiler/conditionalExpressionNewLine7.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine7.ts(2,3): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine7.ts(3,3): error TS2304: Cannot find name 'c'.
==== tests/cases/compiler/conditionalExpressionNewLine7.ts (3 errors) ====
var v = a ?
~
!!! error TS2304: Cannot find name 'a'.
b :
~
!!! error TS2304: Cannot find name 'b'.
c;
~
!!! error TS2304: Cannot find name 'c'.
@@ -0,0 +1,9 @@
//// [conditionalExpressionNewLine7.ts]
var v = a ?
b :
c;
//// [conditionalExpressionNewLine7.js]
var v = a ?
b :
c;
@@ -0,0 +1,27 @@
tests/cases/compiler/conditionalExpressionNewLine8.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine8.ts(2,5): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine8.ts(2,9): error TS2304: Cannot find name 'd'.
tests/cases/compiler/conditionalExpressionNewLine8.ts(2,13): error TS2304: Cannot find name 'e'.
tests/cases/compiler/conditionalExpressionNewLine8.ts(3,5): error TS2304: Cannot find name 'c'.
tests/cases/compiler/conditionalExpressionNewLine8.ts(3,9): error TS2304: Cannot find name 'f'.
tests/cases/compiler/conditionalExpressionNewLine8.ts(3,13): error TS2304: Cannot find name 'g'.
==== tests/cases/compiler/conditionalExpressionNewLine8.ts (7 errors) ====
var v = a
~
!!! error TS2304: Cannot find name 'a'.
? b ? d : e
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS2304: Cannot find name 'd'.
~
!!! error TS2304: Cannot find name 'e'.
: c ? f : g;
~
!!! error TS2304: Cannot find name 'c'.
~
!!! error TS2304: Cannot find name 'f'.
~
!!! error TS2304: Cannot find name 'g'.
@@ -0,0 +1,9 @@
//// [conditionalExpressionNewLine8.ts]
var v = a
? b ? d : e
: c ? f : g;
//// [conditionalExpressionNewLine8.js]
var v = a
? b ? d : e
: c ? f : g;
@@ -0,0 +1,29 @@
tests/cases/compiler/conditionalExpressionNewLine9.ts(1,9): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conditionalExpressionNewLine9.ts(2,5): error TS2304: Cannot find name 'b'.
tests/cases/compiler/conditionalExpressionNewLine9.ts(3,7): error TS2304: Cannot find name 'd'.
tests/cases/compiler/conditionalExpressionNewLine9.ts(3,11): error TS2304: Cannot find name 'e'.
tests/cases/compiler/conditionalExpressionNewLine9.ts(4,5): error TS2304: Cannot find name 'c'.
tests/cases/compiler/conditionalExpressionNewLine9.ts(5,7): error TS2304: Cannot find name 'f'.
tests/cases/compiler/conditionalExpressionNewLine9.ts(5,11): error TS2304: Cannot find name 'g'.
==== tests/cases/compiler/conditionalExpressionNewLine9.ts (7 errors) ====
var v = a
~
!!! error TS2304: Cannot find name 'a'.
? b
~
!!! error TS2304: Cannot find name 'b'.
? d : e
~
!!! error TS2304: Cannot find name 'd'.
~
!!! error TS2304: Cannot find name 'e'.
: c
~
!!! error TS2304: Cannot find name 'c'.
? f : g;
~
!!! error TS2304: Cannot find name 'f'.
~
!!! error TS2304: Cannot find name 'g'.
@@ -0,0 +1,13 @@
//// [conditionalExpressionNewLine9.ts]
var v = a
? b
? d : e
: c
? f : g;
//// [conditionalExpressionNewLine9.js]
var v = a
? b
? d : e
: c
? f : g;
@@ -499,7 +499,8 @@ var CLASS = (function () {
CLASS.prototype.Foo = function () {
var myEvent = function () { return 1; };
if (myEvent() == 1)
return true ? : ;
return true ?
: ;
else
return false;
};
@@ -69,7 +69,10 @@ var TypeScript;
};
PullTypeSymbol.prototype.getScopedNameEx = function (scopeSymbol, useConstraintInName, getPrettyTypeName, getTypeParamMarkerInfo) {
if (this.isArray()) {
var elementMemberName = this._elementType ? (this._elementType.isArray() || this._elementType.isNamedTypeSymbol() ? this._elementType.getScopedNameEx(scopeSymbol, false, getPrettyTypeName, getTypeParamMarkerInfo) : this._elementType.getMemberTypeNameEx(false, scopeSymbol, getPrettyTypeName)) : 1;
var elementMemberName = this._elementType ?
(this._elementType.isArray() || this._elementType.isNamedTypeSymbol() ?
this._elementType.getScopedNameEx(scopeSymbol, false, getPrettyTypeName, getTypeParamMarkerInfo) :
this._elementType.getMemberTypeNameEx(false, scopeSymbol, getPrettyTypeName)) : 1;
return TypeScript.MemberName.create(elementMemberName, "", "[]");
}
};
@@ -43,7 +43,9 @@ var Bugs;
rest[_i - 1] = arguments[_i];
}
var index = rest[0];
return typeof args[index] !== 'undefined' ? args[index] : match;
return typeof args[index] !== 'undefined'
? args[index]
: match;
});
return result;
}
+5 -1
View File
@@ -39,7 +39,11 @@ var CharacterInfo = (function () {
};
CharacterInfo.hexValue = function (c) {
Debug.assert(isHexDigit(c));
return isDecimalDigit(c) ? (c - CharacterCodes._0) : (c >= CharacterCodes.A && c <= CharacterCodes.F) ? c - CharacterCodes.A + 10 : c - CharacterCodes.a + 10;
return isDecimalDigit(c)
? (c - CharacterCodes._0)
: (c >= CharacterCodes.A && c <= CharacterCodes.F)
? c - CharacterCodes.A + 10
: c - CharacterCodes.a + 10;
};
return CharacterInfo;
})();
@@ -105,77 +105,92 @@ function foo12(x: number | string | boolean) {
// the type of a variable or parameter is narrowed by any type guard in the condition when false,
// provided the false expression contains no assignments to the variable or parameter.
function foo(x) {
return typeof x === "string" ? x.length // string
: x++; // number
return typeof x === "string"
? x.length // string
: x++; // number
}
function foo2(x) {
// x is assigned in the if true branch, the type is not narrowed
return typeof x === "string" ? (x = 10 && x) // string | number
: x; // string | number
return typeof x === "string"
? (x = 10 && x) // string | number
: x; // string | number
}
function foo3(x) {
// x is assigned in the if false branch, the type is not narrowed
// even though assigned using same type as narrowed expression
return typeof x === "string" ? (x = "Hello" && x) // string | number
: x; // string | number
return typeof x === "string"
? (x = "Hello" && x) // string | number
: x; // string | number
}
function foo4(x) {
// false branch updates the variable - so here it is not number
// even though assigned using same type as narrowed expression
return typeof x === "string" ? x // string | number
: (x = 10 && x); // string | number
return typeof x === "string"
? x // string | number
: (x = 10 && x); // string | number
}
function foo5(x) {
// false branch updates the variable - so here it is not number
return typeof x === "string" ? x // string | number
: (x = "hello" && x); // string | number
return typeof x === "string"
? x // string | number
: (x = "hello" && x); // string | number
}
function foo6(x) {
// Modify in both branches
return typeof x === "string" ? (x = 10 && x) // string | number
: (x = "hello" && x); // string | number
return typeof x === "string"
? (x = 10 && x) // string | number
: (x = "hello" && x); // string | number
}
function foo7(x) {
return typeof x === "string" ? x === "hello" // string
: typeof x === "boolean" ? x // boolean
: x == 10; // number
return typeof x === "string"
? x === "hello" // string
: typeof x === "boolean"
? x // boolean
: x == 10; // number
}
function foo8(x) {
var b;
return typeof x === "string" ? x === "hello" : ((b = x) &&
(typeof x === "boolean" ? x // boolean
: x == 10)); // number
return typeof x === "string"
? x === "hello"
: ((b = x) &&
(typeof x === "boolean"
? x // boolean
: x == 10)); // number
}
function foo9(x) {
var y = 10;
// usage of x or assignment to separate variable shouldn't cause narrowing of type to stop
return typeof x === "string" ? ((y = x.length) && x === "hello") // string
: x === 10; // number
return typeof x === "string"
? ((y = x.length) && x === "hello") // string
: x === 10; // number
}
function foo10(x) {
// Mixing typeguards
var b;
return typeof x === "string" ? x // string
: ((b = x) // x is number | boolean
&& typeof x === "number"
&& x.toString()); // x is number
return typeof x === "string"
? x // string
: ((b = x) // x is number | boolean
&& typeof x === "number"
&& x.toString()); // x is number
}
function foo11(x) {
// Mixing typeguards
// Assigning value to x deep inside another guard stops narrowing of type too
var b;
return typeof x === "string" ? x // number | boolean | string - changed in the false branch
: ((b = x) // x is number | boolean | string - because the assignment changed it
&& typeof x === "number"
&& (x = 10) // assignment to x
&& x); // x is number | boolean | string
return typeof x === "string"
? x // number | boolean | string - changed in the false branch
: ((b = x) // x is number | boolean | string - because the assignment changed it
&& typeof x === "number"
&& (x = 10) // assignment to x
&& x); // x is number | boolean | string
}
function foo12(x) {
// Mixing typeguards
// Assigning value to x in outer guard shouldn't stop narrowing in the inner expression
var b;
return typeof x === "string" ? (x = 10 && x.toString().length) // number | boolean | string - changed here
: ((b = x) // x is number | boolean | string - changed in true branch
&& typeof x === "number"
&& x); // x is number
return typeof x === "string"
? (x = 10 && x.toString().length) // number | boolean | string - changed here
: ((b = x) // x is number | boolean | string - changed in true branch
&& typeof x === "number"
&& x); // x is number
}
@@ -82,32 +82,44 @@ module m1 {
//// [typeGuardsInFunctionAndModuleBlock.js]
// typeguards are scoped in function/module block
function foo(x) {
return typeof x === "string" ? x : function f() {
var b = x; // number | boolean
return typeof x === "boolean" ? x.toString() // boolean
: x.toString(); // number
}();
return typeof x === "string"
? x
: function f() {
var b = x; // number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
}();
}
function foo2(x) {
return typeof x === "string" ? x : function f(a) {
var b = x; // new scope - number | boolean
return typeof x === "boolean" ? x.toString() // boolean
: x.toString(); // number
}(x); // x here is narrowed to number | boolean
return typeof x === "string"
? x
: function f(a) {
var b = x; // new scope - number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
}(x); // x here is narrowed to number | boolean
}
function foo3(x) {
return typeof x === "string" ? x : (function () {
var b = x; // new scope - number | boolean
return typeof x === "boolean" ? x.toString() // boolean
: x.toString(); // number
})();
return typeof x === "string"
? x
: (function () {
var b = x; // new scope - number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
})();
}
function foo4(x) {
return typeof x === "string" ? x : (function (a) {
var b = x; // new scope - number | boolean
return typeof x === "boolean" ? x.toString() // boolean
: x.toString(); // number
})(x); // x here is narrowed to number | boolean
return typeof x === "string"
? x
: (function (a) {
var b = x; // new scope - number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
})(x); // x here is narrowed to number | boolean
}
// Type guards affect nested function expressions, but not nested function declarations
function foo5(x) {
@@ -129,8 +141,9 @@ var m;
y = x; // string;
}
else {
y = typeof x === "boolean" ? x.toString() // boolean
: x.toString(); // number
y = typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
}
})(m2 || (m2 = {}));
})(m || (m = {}));
@@ -147,8 +160,9 @@ var m1;
y = x; // string;
}
else {
y = typeof x === "boolean" ? x.toString() // boolean
: x.toString(); // number
y = typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
}
})(m3 = m2.m3 || (m2.m3 = {}));
})(m2 || (m2 = {}));
@@ -258,8 +258,9 @@ function foo10(x) {
else {
var y;
var b = x; // number | boolean
return typeof x === "number" ? x === 10 // number
: x; // x should be boolean
return typeof x === "number"
? x === 10 // number
: x; // x should be boolean
}
}
function foo11(x) {
@@ -271,13 +272,15 @@ function foo11(x) {
else {
var y;
var b = x; // number | boolean | string - because below we are changing value of x in if statement
return typeof x === "number" ? (
// change value of x
x = 10 && x.toString() // number | boolean | string
) : (
// do not change value
y = x && x.toString() // number | boolean | string
);
return typeof x === "number"
? (
// change value of x
x = 10 && x.toString() // number | boolean | string
)
: (
// do not change value
y = x && x.toString() // number | boolean | string
);
}
}
function foo12(x) {
@@ -289,7 +292,8 @@ function foo12(x) {
else {
x = 10;
var b = x; // number | boolean | string
return typeof x === "number" ? x.toString() // number
: x.toString(); // boolean | string
return typeof x === "number"
? x.toString() // number
: x.toString(); // boolean | string
}
}
@@ -86,8 +86,8 @@ function foo6(x) {
// Mixing typeguard narrowing in if statement with conditional expression typeguard
return typeof x !== "string" // string | number | boolean
&& (typeof x !== "number" // number | boolean
? x // boolean
: x === 10); // number
? x // boolean
: x === 10); // number
}
function foo7(x) {
var y;
@@ -96,14 +96,16 @@ function foo7(x) {
// Assigning value to x deep inside another guard stops narrowing of type too
return typeof x !== "string"
&& ((z = x) // string | number | boolean - x changed deeper in conditional expression
&& (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string
: (y = x && x.toString()))); // number | boolean | string
&& (typeof x === "number"
? (x = 10 && x.toString()) // number | boolean | string
: (y = x && x.toString()))); // number | boolean | string
}
function foo8(x) {
// Mixing typeguard
// Assigning value to x in outer guard shouldn't stop narrowing in the inner expression
return typeof x !== "string"
&& (x = 10) // change x - number| string
&& (typeof x === "number" ? x // number
: x.length); // string
&& (typeof x === "number"
? x // number
: x.length); // string
}
@@ -86,8 +86,8 @@ function foo6(x) {
// Mixing typeguard
return typeof x === "string" // string | number | boolean
|| (typeof x !== "number" // number | boolean
? x // boolean
: x === 10); // number
? x // boolean
: x === 10); // number
}
function foo7(x) {
var y;
@@ -96,14 +96,16 @@ function foo7(x) {
// Assigning value to x deep inside another guard stops narrowing of type too
return typeof x === "string"
|| ((z = x) // string | number | boolean - x changed deeper in conditional expression
|| (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string
: (y = x && x.toString()))); // number | boolean | string
|| (typeof x === "number"
? (x = 10 && x.toString()) // number | boolean | string
: (y = x && x.toString()))); // number | boolean | string
}
function foo8(x) {
// Mixing typeguard
// Assigning value to x in outer guard shouldn't stop narrowing in the inner expression
return typeof x === "string"
|| (x = 10) // change x - number| string
|| (typeof x === "number" ? x // number
: x.length); // string
|| (typeof x === "number"
? x // number
: x.length); // string
}
@@ -0,0 +1 @@
var v = a ? b : c;
@@ -0,0 +1,7 @@
var v = a
? b
? d
: e
: c
? f
: g;
@@ -0,0 +1,2 @@
var v = a
? b : c;
@@ -0,0 +1,2 @@
var v = a ?
b : c;
@@ -0,0 +1,2 @@
var v = a ? b :
c;
@@ -0,0 +1,2 @@
var v = a ? b
: c;
@@ -0,0 +1,3 @@
var v = a
? b
: c;
@@ -0,0 +1,3 @@
var v = a ?
b :
c;
@@ -0,0 +1,3 @@
var v = a
? b ? d : e
: c ? f : g;
@@ -0,0 +1,5 @@
var v = a
? b
? d : e
: c
? f : g;