From 569cdf1b074dd7462c53102e0f69bfc9863a12d7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:54:21 -0700 Subject: [PATCH] Disallow expression with type parameters as left side of property access (#49464) --- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/parser.ts | 5 +++ .../genericCallWithoutArgs.errors.txt | 5 ++- .../instantiationExpressionErrors.errors.txt | 8 +++- ...ationExpression1(target=es2019).errors.txt | 21 ++++++++++ ...InstantiationExpression1(target=es2019).js | 20 ++++++++++ ...ntiationExpression1(target=es2019).symbols | 39 +++++++++++++++++++ ...tantiationExpression1(target=es2019).types | 37 ++++++++++++++++++ ...ationExpression1(target=es2020).errors.txt | 21 ++++++++++ ...InstantiationExpression1(target=es2020).js | 20 ++++++++++ ...ntiationExpression1(target=es2020).symbols | 39 +++++++++++++++++++ ...tantiationExpression1(target=es2020).types | 37 ++++++++++++++++++ ...InstantiationExpression2(target=es2019).js | 19 +++++++++ ...ntiationExpression2(target=es2019).symbols | 27 +++++++++++++ ...tantiationExpression2(target=es2019).types | 23 +++++++++++ ...InstantiationExpression2(target=es2020).js | 18 +++++++++ ...ntiationExpression2(target=es2020).symbols | 27 +++++++++++++ ...tantiationExpression2(target=es2020).types | 23 +++++++++++ .../parserMemberAccessExpression1.errors.txt | 8 +++- ...erMemberAccessOffOfGenericType1.errors.txt | 7 +++- ...tionalChainWithInstantiationExpression1.ts | 16 ++++++++ ...tionalChainWithInstantiationExpression2.ts | 14 +++++++ 22 files changed, 433 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).errors.txt create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).js create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).symbols create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).types create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).errors.txt create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).js create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).symbols create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).types create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).js create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).symbols create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).types create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).js create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).symbols create mode 100644 tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).types create mode 100644 tests/cases/compiler/optionalChainWithInstantiationExpression1.ts create mode 100644 tests/cases/compiler/optionalChainWithInstantiationExpression2.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3a7f155f12d82..0c914e1625dd0 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1493,6 +1493,10 @@ "category": "Message", "code": 1476 }, + "An instantiation expression cannot be followed by a property access.": { + "category": "Error", + "code": 1477 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8c16ff9a910da..ec10d015c3bc4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5646,6 +5646,11 @@ namespace ts { if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); } + if (isExpressionWithTypeArguments(expression) && expression.typeArguments) { + const pos = expression.typeArguments.pos - 1; + const end = skipTrivia(sourceText, expression.typeArguments.end) + 1; + parseErrorAt(pos, end, Diagnostics.An_instantiation_expression_cannot_be_followed_by_a_property_access); + } return finishNode(propertyAccess, pos); } diff --git a/tests/baselines/reference/genericCallWithoutArgs.errors.txt b/tests/baselines/reference/genericCallWithoutArgs.errors.txt index 75a2d51a1da3e..40ad1145c0109 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.errors.txt +++ b/tests/baselines/reference/genericCallWithoutArgs.errors.txt @@ -1,10 +1,13 @@ +tests/cases/compiler/genericCallWithoutArgs.ts(4,2): error TS1477: An instantiation expression cannot be followed by a property access. tests/cases/compiler/genericCallWithoutArgs.ts(4,18): error TS1003: Identifier expected. -==== tests/cases/compiler/genericCallWithoutArgs.ts (1 errors) ==== +==== tests/cases/compiler/genericCallWithoutArgs.ts (2 errors) ==== function f(x: X, y: Y) { } f. + ~~~~~~~~~~~~~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. !!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/instantiationExpressionErrors.errors.txt b/tests/baselines/reference/instantiationExpressionErrors.errors.txt index 8a725af6b4485..446d469e34295 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.errors.txt +++ b/tests/baselines/reference/instantiationExpressionErrors.errors.txt @@ -1,3 +1,5 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,13): error TS1477: An instantiation expression cannot be followed by a property access. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,13): error TS1477: An instantiation expression cannot be followed by a property access. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(13,12): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string[]'. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(13,14): error TS2693: 'number' only refers to a type, but is being used as a value here. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(18,12): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. @@ -14,7 +16,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(45,12): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. -==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (14 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (16 errors) ==== declare let f: { (): T, g(): U }; // Type arguments in member expressions @@ -22,7 +24,11 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr const a1 = f; // { (): number; g(): U; } const a2 = f.g; // () => number const a3 = f.g; // () => U + ~~~~~~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. const a4 = f.g; // () => number + ~~~~~~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. const a5 = f['g']; // () => number // `[` is an expression starter and cannot immediately follow a type argument list diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).errors.txt b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).errors.txt new file mode 100644 index 0000000000000..4c953e73fd665 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/optionalChainWithInstantiationExpression1.ts(12,5): error TS1477: An instantiation expression cannot be followed by a property access. + + +==== tests/cases/compiler/optionalChainWithInstantiationExpression1.ts (1 errors) ==== + declare namespace A { + export class b { + static d: number; + constructor(x: T); + } + } + + type c = unknown; + + declare const a: typeof A | undefined; + + a?.b.d; + ~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. + + a?.b.d + \ No newline at end of file diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).js b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).js new file mode 100644 index 0000000000000..593e340b04559 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).js @@ -0,0 +1,20 @@ +//// [optionalChainWithInstantiationExpression1.ts] +declare namespace A { + export class b { + static d: number; + constructor(x: T); + } +} + +type c = unknown; + +declare const a: typeof A | undefined; + +a?.b.d; + +a?.b.d + + +//// [optionalChainWithInstantiationExpression1.js] +(a === null || a === void 0 ? void 0 : a.b).d; +a === null || a === void 0 ? void 0 : a.b.d; diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).symbols b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).symbols new file mode 100644 index 0000000000000..160950e459108 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).symbols @@ -0,0 +1,39 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression1.ts === +declare namespace A { +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression1.ts, 0, 0)) + + export class b { +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression1.ts, 1, 19)) + + static d: number; +>d : Symbol(b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) + + constructor(x: T); +>x : Symbol(x, Decl(optionalChainWithInstantiationExpression1.ts, 3, 20)) +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression1.ts, 1, 19)) + } +} + +type c = unknown; +>c : Symbol(c, Decl(optionalChainWithInstantiationExpression1.ts, 5, 1)) + +declare const a: typeof A | undefined; +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression1.ts, 9, 13)) +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression1.ts, 0, 0)) + +a?.b.d; +>a?.b.d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) +>a?.b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression1.ts, 9, 13)) +>b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>c : Symbol(c, Decl(optionalChainWithInstantiationExpression1.ts, 5, 1)) +>d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) + +a?.b.d +>a?.b.d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) +>a?.b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression1.ts, 9, 13)) +>b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).types b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).types new file mode 100644 index 0000000000000..11e0ab6572ae9 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2019).types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression1.ts === +declare namespace A { +>A : typeof A + + export class b { +>b : b + + static d: number; +>d : number + + constructor(x: T); +>x : T + } +} + +type c = unknown; +>c : unknown + +declare const a: typeof A | undefined; +>a : typeof A +>A : typeof A + +a?.b.d; +>a?.b.d : number +>a?.b : { new (x: unknown): A.b; prototype: A.b; d: number; } +>a?.b : typeof A.b +>a : typeof A +>b : typeof A.b +>d : number + +a?.b.d +>a?.b.d : number +>a?.b : typeof A.b +>a : typeof A +>b : typeof A.b +>d : number + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).errors.txt b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).errors.txt new file mode 100644 index 0000000000000..4c953e73fd665 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/optionalChainWithInstantiationExpression1.ts(12,5): error TS1477: An instantiation expression cannot be followed by a property access. + + +==== tests/cases/compiler/optionalChainWithInstantiationExpression1.ts (1 errors) ==== + declare namespace A { + export class b { + static d: number; + constructor(x: T); + } + } + + type c = unknown; + + declare const a: typeof A | undefined; + + a?.b.d; + ~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. + + a?.b.d + \ No newline at end of file diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).js b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).js new file mode 100644 index 0000000000000..86f3e9f520934 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).js @@ -0,0 +1,20 @@ +//// [optionalChainWithInstantiationExpression1.ts] +declare namespace A { + export class b { + static d: number; + constructor(x: T); + } +} + +type c = unknown; + +declare const a: typeof A | undefined; + +a?.b.d; + +a?.b.d + + +//// [optionalChainWithInstantiationExpression1.js] +a?.b.d; +a?.b.d; diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).symbols b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).symbols new file mode 100644 index 0000000000000..160950e459108 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).symbols @@ -0,0 +1,39 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression1.ts === +declare namespace A { +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression1.ts, 0, 0)) + + export class b { +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression1.ts, 1, 19)) + + static d: number; +>d : Symbol(b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) + + constructor(x: T); +>x : Symbol(x, Decl(optionalChainWithInstantiationExpression1.ts, 3, 20)) +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression1.ts, 1, 19)) + } +} + +type c = unknown; +>c : Symbol(c, Decl(optionalChainWithInstantiationExpression1.ts, 5, 1)) + +declare const a: typeof A | undefined; +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression1.ts, 9, 13)) +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression1.ts, 0, 0)) + +a?.b.d; +>a?.b.d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) +>a?.b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression1.ts, 9, 13)) +>b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>c : Symbol(c, Decl(optionalChainWithInstantiationExpression1.ts, 5, 1)) +>d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) + +a?.b.d +>a?.b.d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) +>a?.b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression1.ts, 9, 13)) +>b : Symbol(A.b, Decl(optionalChainWithInstantiationExpression1.ts, 0, 21)) +>d : Symbol(A.b.d, Decl(optionalChainWithInstantiationExpression1.ts, 1, 23)) + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).types b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).types new file mode 100644 index 0000000000000..11e0ab6572ae9 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression1(target=es2020).types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression1.ts === +declare namespace A { +>A : typeof A + + export class b { +>b : b + + static d: number; +>d : number + + constructor(x: T); +>x : T + } +} + +type c = unknown; +>c : unknown + +declare const a: typeof A | undefined; +>a : typeof A +>A : typeof A + +a?.b.d; +>a?.b.d : number +>a?.b : { new (x: unknown): A.b; prototype: A.b; d: number; } +>a?.b : typeof A.b +>a : typeof A +>b : typeof A.b +>d : number + +a?.b.d +>a?.b.d : number +>a?.b : typeof A.b +>a : typeof A +>b : typeof A.b +>d : number + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).js b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).js new file mode 100644 index 0000000000000..e5c499eb06325 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).js @@ -0,0 +1,19 @@ +//// [optionalChainWithInstantiationExpression2.ts] +declare interface A { + c: number; + (): T; +} + +type b = 'b type'; + +declare const a: A | undefined; + +a?.(); + +a?.(); + + +//// [optionalChainWithInstantiationExpression2.js] +var _a; +a === null || a === void 0 ? void 0 : a(); +(_a = (a)) === null || _a === void 0 ? void 0 : _a(); diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).symbols b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).symbols new file mode 100644 index 0000000000000..9da7857d2d3c3 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression2.ts === +declare interface A { +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression2.ts, 0, 0)) + + c: number; +>c : Symbol(A.c, Decl(optionalChainWithInstantiationExpression2.ts, 0, 21)) + + (): T; +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression2.ts, 2, 5)) +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression2.ts, 2, 5)) +} + +type b = 'b type'; +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression2.ts, 3, 1)) + +declare const a: A | undefined; +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression2.ts, 7, 13)) +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression2.ts, 0, 0)) + +a?.(); +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression2.ts, 7, 13)) +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression2.ts, 3, 1)) + +a?.(); +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression2.ts, 7, 13)) +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression2.ts, 3, 1)) + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).types b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).types new file mode 100644 index 0000000000000..67fc79bb5df18 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2019).types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression2.ts === +declare interface A { + c: number; +>c : number + + (): T; +} + +type b = 'b type'; +>b : "b type" + +declare const a: A | undefined; +>a : A + +a?.(); +>a?.() : "b type" +>a : A + +a?.(); +>a?.() : "b type" +>a : { (): "b type"; c: number; } +>a : A + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).js b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).js new file mode 100644 index 0000000000000..9cca16c431b87 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).js @@ -0,0 +1,18 @@ +//// [optionalChainWithInstantiationExpression2.ts] +declare interface A { + c: number; + (): T; +} + +type b = 'b type'; + +declare const a: A | undefined; + +a?.(); + +a?.(); + + +//// [optionalChainWithInstantiationExpression2.js] +a?.(); +a?.(); diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).symbols b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).symbols new file mode 100644 index 0000000000000..9da7857d2d3c3 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression2.ts === +declare interface A { +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression2.ts, 0, 0)) + + c: number; +>c : Symbol(A.c, Decl(optionalChainWithInstantiationExpression2.ts, 0, 21)) + + (): T; +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression2.ts, 2, 5)) +>T : Symbol(T, Decl(optionalChainWithInstantiationExpression2.ts, 2, 5)) +} + +type b = 'b type'; +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression2.ts, 3, 1)) + +declare const a: A | undefined; +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression2.ts, 7, 13)) +>A : Symbol(A, Decl(optionalChainWithInstantiationExpression2.ts, 0, 0)) + +a?.(); +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression2.ts, 7, 13)) +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression2.ts, 3, 1)) + +a?.(); +>a : Symbol(a, Decl(optionalChainWithInstantiationExpression2.ts, 7, 13)) +>b : Symbol(b, Decl(optionalChainWithInstantiationExpression2.ts, 3, 1)) + diff --git a/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).types b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).types new file mode 100644 index 0000000000000..67fc79bb5df18 --- /dev/null +++ b/tests/baselines/reference/optionalChainWithInstantiationExpression2(target=es2020).types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/optionalChainWithInstantiationExpression2.ts === +declare interface A { + c: number; +>c : number + + (): T; +} + +type b = 'b type'; +>b : "b type" + +declare const a: A | undefined; +>a : A + +a?.(); +>a?.() : "b type" +>a : A + +a?.(); +>a?.() : "b type" +>a : { (): "b type"; c: number; } +>a : A + diff --git a/tests/baselines/reference/parserMemberAccessExpression1.errors.txt b/tests/baselines/reference/parserMemberAccessExpression1.errors.txt index f791d4dc1caec..a427715dbd793 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessExpression1.errors.txt @@ -3,11 +3,13 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,1): error TS2304: Cannot find name 'Foo'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,9): error TS2304: Cannot find name 'T'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,4): error TS1477: An instantiation expression cannot be followed by a property access. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,4): error TS1477: An instantiation expression cannot be followed by a property access. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,12): error TS2304: Cannot find name 'T'. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (7 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (9 errors) ==== Foo(); ~~~ !!! error TS2304: Cannot find name 'Foo'. @@ -21,9 +23,13 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression Foo.Bar(); ~~~ !!! error TS2304: Cannot find name 'Foo'. + ~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. Foo.Bar(); ~~~ !!! error TS2304: Cannot find name 'Foo'. + ~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. ~ !!! error TS2304: Cannot find name 'T'. \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt index d0ffa095c3ee7..51db92cbdfc09 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt @@ -1,7 +1,10 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,9): error TS2304: Cannot find name 'List'. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,13): error TS1477: An instantiation expression cannot be followed by a property access. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (1 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (2 errors) ==== var v = List.makeChild(); ~~~~ -!!! error TS2304: Cannot find name 'List'. \ No newline at end of file +!!! error TS2304: Cannot find name 'List'. + ~~~~~~~~ +!!! error TS1477: An instantiation expression cannot be followed by a property access. \ No newline at end of file diff --git a/tests/cases/compiler/optionalChainWithInstantiationExpression1.ts b/tests/cases/compiler/optionalChainWithInstantiationExpression1.ts new file mode 100644 index 0000000000000..6bc4c947195ad --- /dev/null +++ b/tests/cases/compiler/optionalChainWithInstantiationExpression1.ts @@ -0,0 +1,16 @@ +// @target: es2019,es2020 + +declare namespace A { + export class b { + static d: number; + constructor(x: T); + } +} + +type c = unknown; + +declare const a: typeof A | undefined; + +a?.b.d; + +a?.b.d diff --git a/tests/cases/compiler/optionalChainWithInstantiationExpression2.ts b/tests/cases/compiler/optionalChainWithInstantiationExpression2.ts new file mode 100644 index 0000000000000..6f719e434b6d1 --- /dev/null +++ b/tests/cases/compiler/optionalChainWithInstantiationExpression2.ts @@ -0,0 +1,14 @@ +// @target: es2019,es2020 + +declare interface A { + c: number; + (): T; +} + +type b = 'b type'; + +declare const a: A | undefined; + +a?.(); + +a?.();