From e7ec9b132c7d6764b0735f8cc77f8b10c57b3bc3 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 12 Sep 2017 16:54:44 -0700 Subject: [PATCH] Initial support for throw expressions --- src/compiler/binder.ts | 4 ++ src/compiler/checker.ts | 7 +++ src/compiler/emitter.ts | 7 +++ src/compiler/factory.ts | 12 +++++ src/compiler/parser.ts | 29 +++++++++++- src/compiler/transformers/esnext.ts | 24 ++++++++++ src/compiler/types.ts | 6 +++ src/compiler/utilities.ts | 8 ++++ src/compiler/visitor.ts | 7 ++- src/services/utilities.ts | 3 +- .../reference/throwExpressions.es2015.js | 16 +++++++ .../reference/throwExpressions.es2015.symbols | 31 ++++++++++++ .../reference/throwExpressions.es2015.types | 47 +++++++++++++++++++ .../reference/throwExpressions.esnext.js | 15 ++++++ .../reference/throwExpressions.esnext.symbols | 31 ++++++++++++ .../reference/throwExpressions.esnext.types | 47 +++++++++++++++++++ .../throwExpressions.es2015.ts | 8 ++++ .../throwExpressions.esnext.ts | 8 ++++ 18 files changed, 307 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/throwExpressions.es2015.js create mode 100644 tests/baselines/reference/throwExpressions.es2015.symbols create mode 100644 tests/baselines/reference/throwExpressions.es2015.types create mode 100644 tests/baselines/reference/throwExpressions.esnext.js create mode 100644 tests/baselines/reference/throwExpressions.esnext.symbols create mode 100644 tests/baselines/reference/throwExpressions.esnext.types create mode 100644 tests/cases/conformance/expressions/throwExpressions/throwExpressions.es2015.ts create mode 100644 tests/cases/conformance/expressions/throwExpressions/throwExpressions.esnext.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 97e60777159..fd0808f0930 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3255,6 +3255,10 @@ namespace ts { let excludeFlags = TransformFlags.NodeExcludes; switch (kind) { + case SyntaxKind.ThrowExpression: + transformFlags |= TransformFlags.AssertESNext; + break; + case SyntaxKind.AsyncKeyword: case SyntaxKind.AwaitExpression: // async/await is ES2017 syntax, but may be ESNext syntax (for async generators) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c87062a212f..db8b0a542e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17178,6 +17178,11 @@ namespace ts { return booleanType; } + function checkThrowExpression(node: ThrowExpression): Type { + checkExpression(node.expression); + return neverType; + } + function checkTypeOfExpression(node: TypeOfExpression): Type { checkExpression(node.expression); return typeofType; @@ -18140,6 +18145,8 @@ namespace ts { return checkMetaProperty(node); case SyntaxKind.DeleteExpression: return checkDeleteExpression(node); + case SyntaxKind.ThrowExpression: + return checkThrowExpression(node); case SyntaxKind.VoidExpression: return checkVoidExpression(node); case SyntaxKind.AwaitExpression: diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8788e0c02f4..4486be5553d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -784,6 +784,8 @@ namespace ts { return emitArrowFunction(node); case SyntaxKind.DeleteExpression: return emitDeleteExpression(node); + case SyntaxKind.ThrowExpression: + return emitThrowExpression(node); case SyntaxKind.TypeOfExpression: return emitTypeOfExpression(node); case SyntaxKind.VoidExpression: @@ -1300,6 +1302,11 @@ namespace ts { emitExpression(node.expression); } + function emitThrowExpression(node: ThrowExpression) { + write("throw "); + emitExpression(node.expression); + } + function emitTypeOfExpression(node: TypeOfExpression) { write("typeof "); emitExpression(node.expression); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 0369be30076..9f93c6e1874 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1074,6 +1074,18 @@ namespace ts { : node; } + export function createThrowExpression(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ThrowExpression); + node.expression = parenthesizePrefixOperand(expression); + return node; + } + + export function updateThrowExpression(node: ThrowExpression, expression: Expression) { + return node.expression !== expression + ? updateNode(createThrowExpression(expression), node) + : node; + } + export function createTypeOf(expression: Expression) { const node = createSynthesizedNode(SyntaxKind.TypeOfExpression); node.expression = parenthesizePrefixOperand(expression); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 63f1696832b..828e3409306 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -185,6 +185,8 @@ namespace ts { return visitNode(cbNode, (node).expression); case SyntaxKind.DeleteExpression: return visitNode(cbNode, (node).expression); + case SyntaxKind.ThrowExpression: + return visitNode(cbNode, (node).expression); case SyntaxKind.TypeOfExpression: return visitNode(cbNode, (node).expression); case SyntaxKind.VoidExpression: @@ -2962,6 +2964,7 @@ namespace ts { case SyntaxKind.ExclamationToken: case SyntaxKind.DeleteKeyword: case SyntaxKind.TypeOfKeyword: + case SyntaxKind.ThrowKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: @@ -2986,11 +2989,21 @@ namespace ts { } function isStartOfExpressionStatement(): boolean { - // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. + // As per the grammar, none of '{', 'function', 'async [no LineTerminator here] function', 'class', 'let [', or 'throw' can start an expression statement: + // + // An |ExpressionStatement| cannot start with a U+007B (LEFT CURLY BRACKET) because that might make it ambiguous with a |Block|. + // An |ExpressionStatement| cannot start with the `function` or `class` keywords because that would make it ambiguous with a |FunctionDeclaration|, a |GeneratorDeclaration|, or a |ClassDeclaration|. + // An |ExpressionStatement| cannot start with `async` `function` because that would make it ambiguous with an |AsyncFunctionDeclaration|. + // An |ExpressionStatement| cannot start with the two token sequence `let` `[` because that would make it ambiguous with a `let` |LexicalDeclaration| whose first |LexicalBinding| was an |ArrayBindingPattern|. + // An |ExpressionStatement| cannot start with `throw` because that would make it ambiguous with a |ThrowStatement|. + // return token() !== SyntaxKind.OpenBraceToken && token() !== SyntaxKind.FunctionKeyword && token() !== SyntaxKind.ClassKeyword && + token() !== SyntaxKind.ThrowKeyword && token() !== SyntaxKind.AtToken && + (token() !== SyntaxKind.AsyncKeyword || !lookAhead(nextTokenIsFunctionKeywordOnSameLine)) && + (token() !== SyntaxKind.LetKeyword || !lookAhead(nextTokenIsOpenBracket)) && isStartOfExpression(); } @@ -3624,6 +3637,13 @@ namespace ts { return finishNode(node); } + function parseThrowExpression() { + const node = createNode(SyntaxKind.ThrowExpression); + nextToken(); + node.expression = parseSimpleUnaryExpression(); + return finishNode(node); + } + function parseTypeOfExpression() { const node = createNode(SyntaxKind.TypeOfExpression); nextToken(); @@ -3730,6 +3750,8 @@ namespace ts { return parsePrefixUnaryExpression(); case SyntaxKind.DeleteKeyword: return parseDeleteExpression(); + case SyntaxKind.ThrowKeyword: + return parseThrowExpression(); case SyntaxKind.TypeOfKeyword: return parseTypeOfExpression(); case SyntaxKind.VoidKeyword: @@ -3768,6 +3790,7 @@ namespace ts { case SyntaxKind.TildeToken: case SyntaxKind.ExclamationToken: case SyntaxKind.DeleteKeyword: + case SyntaxKind.ThrowKeyword: case SyntaxKind.TypeOfKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.AwaitKeyword: @@ -5774,6 +5797,10 @@ namespace ts { return nextToken() === SyntaxKind.OpenParenToken; } + function nextTokenIsOpenBracket() { + return nextToken() === SyntaxKind.OpenBracketToken; + } + function nextTokenIsSlash() { return nextToken() === SyntaxKind.SlashToken; } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 0fca09b4540..ac74b302fdc 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -79,6 +79,8 @@ namespace ts { return visitForOfStatement(node as ForOfStatement, /*outermostLabeledStatement*/ undefined); case SyntaxKind.ForStatement: return visitForStatement(node as ForStatement); + case SyntaxKind.ThrowExpression: + return visitThrowExpression(node as ThrowExpression); case SyntaxKind.VoidExpression: return visitVoidExpression(node as VoidExpression); case SyntaxKind.Constructor: @@ -278,6 +280,10 @@ namespace ts { ); } + function visitThrowExpression(node: ThrowExpression) { + return createThrowHelper(context, visitNode(node.expression, visitor, isExpression), node); + } + function visitVoidExpression(node: VoidExpression) { return visitEachChild(node, visitorNoDestructuringValue, context); } @@ -987,4 +993,22 @@ namespace ts { location ); } + + const throwHelper: EmitHelper = { + name: "typescript:throw", + scoped: false, + text: `var __throw = (this && this.__throw) || function (e) { throw e; };` + }; + + function createThrowHelper(context: TransformationContext, expression: Expression, location?: TextRange) { + context.requestEmitHelper(throwHelper); + return setTextRange( + createCall( + getHelperName("__throw"), + /*typeArguments*/ undefined, + [expression] + ), + location + ); + } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index cfb08a7b05a..48241efb04a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -257,6 +257,7 @@ namespace ts { FunctionExpression, ArrowFunction, DeleteExpression, + ThrowExpression, TypeOfExpression, VoidExpression, AwaitExpression, @@ -1155,6 +1156,11 @@ namespace ts { expression: UnaryExpression; } + export interface ThrowExpression extends UnaryExpression { + kind: SyntaxKind.ThrowExpression; + expression: UnaryExpression; + } + export interface TypeOfExpression extends UnaryExpression { kind: SyntaxKind.TypeOfExpression; expression: UnaryExpression; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ee450344827..b255e9986eb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1227,6 +1227,7 @@ namespace ts { case SyntaxKind.ArrowFunction: case SyntaxKind.VoidExpression: case SyntaxKind.DeleteExpression: + case SyntaxKind.ThrowExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: @@ -2129,6 +2130,7 @@ namespace ts { case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.VoidExpression: + case SyntaxKind.ThrowExpression: case SyntaxKind.DeleteExpression: case SyntaxKind.AwaitExpression: case SyntaxKind.ConditionalExpression: @@ -2216,6 +2218,7 @@ namespace ts { case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.VoidExpression: + case SyntaxKind.ThrowExpression: case SyntaxKind.DeleteExpression: case SyntaxKind.AwaitExpression: return 15; @@ -4294,6 +4297,10 @@ namespace ts { return node.kind === SyntaxKind.DeleteExpression; } + export function isThrowExpression(node: Node): node is ThrowExpression { + return node.kind === SyntaxKind.ThrowExpression; + } + export function isTypeOfExpression(node: Node): node is TypeOfExpression { return node.kind === SyntaxKind.AwaitExpression; } @@ -5112,6 +5119,7 @@ namespace ts { case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: case SyntaxKind.DeleteExpression: + case SyntaxKind.ThrowExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.VoidExpression: case SyntaxKind.AwaitExpression: diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 7d46630e227..266ebc218b9 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -495,6 +495,10 @@ namespace ts { return updateDelete(node, visitNode((node).expression, visitor, isExpression)); + case SyntaxKind.ThrowExpression: + return updateThrowExpression(node, + visitNode((node).expression, visitor, isExpression)); + case SyntaxKind.TypeOfExpression: return updateTypeOf(node, visitNode((node).expression, visitor, isExpression)); @@ -1104,13 +1108,14 @@ namespace ts { case SyntaxKind.ParenthesizedExpression: case SyntaxKind.DeleteExpression: + case SyntaxKind.ThrowExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.VoidExpression: case SyntaxKind.AwaitExpression: case SyntaxKind.YieldExpression: case SyntaxKind.SpreadElement: case SyntaxKind.NonNullExpression: - result = reduceNode((node).expression, cbNode, result); + result = reduceNode((node).expression, cbNode, result); break; case SyntaxKind.PrefixUnaryExpression: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c3a1d5d571d..712421f3e3c 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -535,12 +535,13 @@ namespace ts { case SyntaxKind.TypeQuery: return isCompletedNode((n).exprName, sourceFile); + case SyntaxKind.ThrowExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.DeleteExpression: case SyntaxKind.VoidExpression: case SyntaxKind.YieldExpression: case SyntaxKind.SpreadElement: - const unaryWordExpression = n as (TypeOfExpression | DeleteExpression | VoidExpression | YieldExpression | SpreadElement); + const unaryWordExpression = n as (ThrowExpression | TypeOfExpression | DeleteExpression | VoidExpression | YieldExpression | SpreadElement); return isCompletedNode(unaryWordExpression.expression, sourceFile); case SyntaxKind.TaggedTemplateExpression: diff --git a/tests/baselines/reference/throwExpressions.es2015.js b/tests/baselines/reference/throwExpressions.es2015.js new file mode 100644 index 00000000000..766497aea52 --- /dev/null +++ b/tests/baselines/reference/throwExpressions.es2015.js @@ -0,0 +1,16 @@ +//// [throwExpressions.es2015.ts] +declare const condition: boolean; +const a = condition ? 1 : throw new Error(); +const b = condition || throw new Error(); +function c(d = throw new TypeError()) { } + +const x = "x", y = "y", z = "z"; +const w = condition ? throw true ? x : y : z; + +//// [throwExpressions.es2015.js] +var __throw = (this && this.__throw) || function (e) { throw e; }; +const a = condition ? 1 : __throw(new Error()); +const b = condition || __throw(new Error()); +function c(d = __throw(new TypeError())) { } +const x = "x", y = "y", z = "z"; +const w = condition ? __throw(true) ? x : y : z; diff --git a/tests/baselines/reference/throwExpressions.es2015.symbols b/tests/baselines/reference/throwExpressions.es2015.symbols new file mode 100644 index 00000000000..9457198e212 --- /dev/null +++ b/tests/baselines/reference/throwExpressions.es2015.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/expressions/throwExpressions/throwExpressions.es2015.ts === +declare const condition: boolean; +>condition : Symbol(condition, Decl(throwExpressions.es2015.ts, 0, 13)) + +const a = condition ? 1 : throw new Error(); +>a : Symbol(a, Decl(throwExpressions.es2015.ts, 1, 5)) +>condition : Symbol(condition, Decl(throwExpressions.es2015.ts, 0, 13)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +const b = condition || throw new Error(); +>b : Symbol(b, Decl(throwExpressions.es2015.ts, 2, 5)) +>condition : Symbol(condition, Decl(throwExpressions.es2015.ts, 0, 13)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +function c(d = throw new TypeError()) { } +>c : Symbol(c, Decl(throwExpressions.es2015.ts, 2, 41)) +>d : Symbol(d, Decl(throwExpressions.es2015.ts, 3, 11)) +>TypeError : Symbol(TypeError, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +const x = "x", y = "y", z = "z"; +>x : Symbol(x, Decl(throwExpressions.es2015.ts, 5, 5)) +>y : Symbol(y, Decl(throwExpressions.es2015.ts, 5, 14)) +>z : Symbol(z, Decl(throwExpressions.es2015.ts, 5, 23)) + +const w = condition ? throw true ? x : y : z; +>w : Symbol(w, Decl(throwExpressions.es2015.ts, 6, 5)) +>condition : Symbol(condition, Decl(throwExpressions.es2015.ts, 0, 13)) +>x : Symbol(x, Decl(throwExpressions.es2015.ts, 5, 5)) +>y : Symbol(y, Decl(throwExpressions.es2015.ts, 5, 14)) +>z : Symbol(z, Decl(throwExpressions.es2015.ts, 5, 23)) + diff --git a/tests/baselines/reference/throwExpressions.es2015.types b/tests/baselines/reference/throwExpressions.es2015.types new file mode 100644 index 00000000000..cc8ed80f5f6 --- /dev/null +++ b/tests/baselines/reference/throwExpressions.es2015.types @@ -0,0 +1,47 @@ +=== tests/cases/conformance/expressions/throwExpressions/throwExpressions.es2015.ts === +declare const condition: boolean; +>condition : boolean + +const a = condition ? 1 : throw new Error(); +>a : 1 +>condition ? 1 : throw new Error() : 1 +>condition : boolean +>1 : 1 +>throw new Error() : never +>new Error() : Error +>Error : ErrorConstructor + +const b = condition || throw new Error(); +>b : true +>condition || throw new Error() : true +>condition : true +>throw new Error() : never +>new Error() : Error +>Error : ErrorConstructor + +function c(d = throw new TypeError()) { } +>c : (d?: never) => void +>d : never +>throw new TypeError() : never +>new TypeError() : TypeError +>TypeError : TypeErrorConstructor + +const x = "x", y = "y", z = "z"; +>x : "x" +>"x" : "x" +>y : "y" +>"y" : "y" +>z : "z" +>"z" : "z" + +const w = condition ? throw true ? x : y : z; +>w : "x" | "y" | "z" +>condition ? throw true ? x : y : z : "x" | "y" | "z" +>condition : true +>throw true ? x : y : "x" | "y" +>throw true : never +>true : true +>x : "x" +>y : "y" +>z : "z" + diff --git a/tests/baselines/reference/throwExpressions.esnext.js b/tests/baselines/reference/throwExpressions.esnext.js new file mode 100644 index 00000000000..da15d7245c9 --- /dev/null +++ b/tests/baselines/reference/throwExpressions.esnext.js @@ -0,0 +1,15 @@ +//// [throwExpressions.esnext.ts] +declare const condition: boolean; +const a = condition ? 1 : throw new Error(); +const b = condition || throw new Error(); +function c(d = throw new TypeError()) { } + +const x = "x", y = "y", z = "z"; +const w = condition ? throw true ? x : y : z; + +//// [throwExpressions.esnext.js] +const a = condition ? 1 : throw new Error(); +const b = condition || throw new Error(); +function c(d = throw new TypeError()) { } +const x = "x", y = "y", z = "z"; +const w = condition ? throw true ? x : y : z; diff --git a/tests/baselines/reference/throwExpressions.esnext.symbols b/tests/baselines/reference/throwExpressions.esnext.symbols new file mode 100644 index 00000000000..2caad23aa58 --- /dev/null +++ b/tests/baselines/reference/throwExpressions.esnext.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/expressions/throwExpressions/throwExpressions.esnext.ts === +declare const condition: boolean; +>condition : Symbol(condition, Decl(throwExpressions.esnext.ts, 0, 13)) + +const a = condition ? 1 : throw new Error(); +>a : Symbol(a, Decl(throwExpressions.esnext.ts, 1, 5)) +>condition : Symbol(condition, Decl(throwExpressions.esnext.ts, 0, 13)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +const b = condition || throw new Error(); +>b : Symbol(b, Decl(throwExpressions.esnext.ts, 2, 5)) +>condition : Symbol(condition, Decl(throwExpressions.esnext.ts, 0, 13)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +function c(d = throw new TypeError()) { } +>c : Symbol(c, Decl(throwExpressions.esnext.ts, 2, 41)) +>d : Symbol(d, Decl(throwExpressions.esnext.ts, 3, 11)) +>TypeError : Symbol(TypeError, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +const x = "x", y = "y", z = "z"; +>x : Symbol(x, Decl(throwExpressions.esnext.ts, 5, 5)) +>y : Symbol(y, Decl(throwExpressions.esnext.ts, 5, 14)) +>z : Symbol(z, Decl(throwExpressions.esnext.ts, 5, 23)) + +const w = condition ? throw true ? x : y : z; +>w : Symbol(w, Decl(throwExpressions.esnext.ts, 6, 5)) +>condition : Symbol(condition, Decl(throwExpressions.esnext.ts, 0, 13)) +>x : Symbol(x, Decl(throwExpressions.esnext.ts, 5, 5)) +>y : Symbol(y, Decl(throwExpressions.esnext.ts, 5, 14)) +>z : Symbol(z, Decl(throwExpressions.esnext.ts, 5, 23)) + diff --git a/tests/baselines/reference/throwExpressions.esnext.types b/tests/baselines/reference/throwExpressions.esnext.types new file mode 100644 index 00000000000..2b043748f14 --- /dev/null +++ b/tests/baselines/reference/throwExpressions.esnext.types @@ -0,0 +1,47 @@ +=== tests/cases/conformance/expressions/throwExpressions/throwExpressions.esnext.ts === +declare const condition: boolean; +>condition : boolean + +const a = condition ? 1 : throw new Error(); +>a : 1 +>condition ? 1 : throw new Error() : 1 +>condition : boolean +>1 : 1 +>throw new Error() : never +>new Error() : Error +>Error : ErrorConstructor + +const b = condition || throw new Error(); +>b : true +>condition || throw new Error() : true +>condition : true +>throw new Error() : never +>new Error() : Error +>Error : ErrorConstructor + +function c(d = throw new TypeError()) { } +>c : (d?: never) => void +>d : never +>throw new TypeError() : never +>new TypeError() : TypeError +>TypeError : TypeErrorConstructor + +const x = "x", y = "y", z = "z"; +>x : "x" +>"x" : "x" +>y : "y" +>"y" : "y" +>z : "z" +>"z" : "z" + +const w = condition ? throw true ? x : y : z; +>w : "x" | "y" | "z" +>condition ? throw true ? x : y : z : "x" | "y" | "z" +>condition : true +>throw true ? x : y : "x" | "y" +>throw true : never +>true : true +>x : "x" +>y : "y" +>z : "z" + diff --git a/tests/cases/conformance/expressions/throwExpressions/throwExpressions.es2015.ts b/tests/cases/conformance/expressions/throwExpressions/throwExpressions.es2015.ts new file mode 100644 index 00000000000..fc665db0b03 --- /dev/null +++ b/tests/cases/conformance/expressions/throwExpressions/throwExpressions.es2015.ts @@ -0,0 +1,8 @@ +// @target: es2015 +declare const condition: boolean; +const a = condition ? 1 : throw new Error(); +const b = condition || throw new Error(); +function c(d = throw new TypeError()) { } + +const x = "x", y = "y", z = "z"; +const w = condition ? throw true ? x : y : z; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/throwExpressions/throwExpressions.esnext.ts b/tests/cases/conformance/expressions/throwExpressions/throwExpressions.esnext.ts new file mode 100644 index 00000000000..2a41f11e19f --- /dev/null +++ b/tests/cases/conformance/expressions/throwExpressions/throwExpressions.esnext.ts @@ -0,0 +1,8 @@ +// @target: esnext +declare const condition: boolean; +const a = condition ? 1 : throw new Error(); +const b = condition || throw new Error(); +function c(d = throw new TypeError()) { } + +const x = "x", y = "y", z = "z"; +const w = condition ? throw true ? x : y : z; \ No newline at end of file