Skip to content

Commit 2cb8ee2

Browse files
authored
fix(48653): throw an error on an invalid optional chain from new expression (#48656)
1 parent c6447f9 commit 2cb8ee2

7 files changed

+85
-0
lines changed

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,10 @@
651651
"category": "Error",
652652
"code": 1208
653653
},
654+
"Invalid optional chain from new expression. Did you mean to call '{0}()'?": {
655+
"category": "Error",
656+
"code": 1209
657+
},
654658
"Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of '{0}'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode.": {
655659
"category": "Error",
656660
"code": 1210

src/compiler/parser.ts

+3
Original file line numberDiff line numberDiff line change
@@ -5942,6 +5942,9 @@ namespace ts {
59425942
typeArguments = (expression as ExpressionWithTypeArguments).typeArguments;
59435943
expression = (expression as ExpressionWithTypeArguments).expression;
59445944
}
5945+
if (token() === SyntaxKind.QuestionDotToken) {
5946+
parseErrorAtCurrentToken(Diagnostics.Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0, getTextOfNodeFromSourceText(sourceText, expression));
5947+
}
59455948
const argumentList = token() === SyntaxKind.OpenParenToken ? parseArgumentList() : undefined;
59465949
return finishNode(factory.createNewExpression(expression, typeArguments, argumentList), pos);
59475950
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
tests/cases/compiler/invalidOptionalChainFromNewExpression.ts(5,6): error TS1209: Invalid optional chain from new expression. Did you mean to call 'A()'?
2+
3+
4+
==== tests/cases/compiler/invalidOptionalChainFromNewExpression.ts (1 errors) ====
5+
class A {
6+
b() {}
7+
}
8+
9+
new A?.b() // error
10+
~~
11+
!!! error TS1209: Invalid optional chain from new expression. Did you mean to call 'A()'?
12+
new A()?.b() // ok
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [invalidOptionalChainFromNewExpression.ts]
2+
class A {
3+
b() {}
4+
}
5+
6+
new A?.b() // error
7+
new A()?.b() // ok
8+
9+
10+
//// [invalidOptionalChainFromNewExpression.js]
11+
var _a, _b;
12+
var A = /** @class */ (function () {
13+
function A() {
14+
}
15+
A.prototype.b = function () { };
16+
return A;
17+
}());
18+
(_a = new A) === null || _a === void 0 ? void 0 : _a.b(); // error
19+
(_b = new A()) === null || _b === void 0 ? void 0 : _b.b(); // ok
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
=== tests/cases/compiler/invalidOptionalChainFromNewExpression.ts ===
2+
class A {
3+
>A : Symbol(A, Decl(invalidOptionalChainFromNewExpression.ts, 0, 0))
4+
5+
b() {}
6+
>b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9))
7+
}
8+
9+
new A?.b() // error
10+
>new A?.b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9))
11+
>A : Symbol(A, Decl(invalidOptionalChainFromNewExpression.ts, 0, 0))
12+
>b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9))
13+
14+
new A()?.b() // ok
15+
>new A()?.b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9))
16+
>A : Symbol(A, Decl(invalidOptionalChainFromNewExpression.ts, 0, 0))
17+
>b : Symbol(A.b, Decl(invalidOptionalChainFromNewExpression.ts, 0, 9))
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/invalidOptionalChainFromNewExpression.ts ===
2+
class A {
3+
>A : A
4+
5+
b() {}
6+
>b : () => void
7+
}
8+
9+
new A?.b() // error
10+
>new A?.b() : void
11+
>new A?.b : () => void
12+
>new A : A
13+
>A : typeof A
14+
>b : () => void
15+
16+
new A()?.b() // ok
17+
>new A()?.b() : void
18+
>new A()?.b : () => void
19+
>new A() : A
20+
>A : typeof A
21+
>b : () => void
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class A {
2+
b() {}
3+
}
4+
5+
new A?.b() // error
6+
new A()?.b() // ok

0 commit comments

Comments
 (0)