mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Preserve newlines for conditional expressions
This commit is contained in:
+46
-5
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user