diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b44b86e971a7a..fbcf3b279714c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5732,9 +5732,18 @@ namespace ts { case SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` case SyntaxKind.TemplateHead: // foo `...${100}...` return true; + // A type argument list followed by `<` never makes sense, and a type argument list followed + // by `>` is ambiguous with a (re-scanned) `>>` operator, so we disqualify both. Also, in + // this context, `+` and `-` are unary operators, not binary operators. + case SyntaxKind.LessThanToken: + case SyntaxKind.GreaterThanToken: + case SyntaxKind.PlusToken: + case SyntaxKind.MinusToken: + return false; } - // Consider something a type argument list only if the following token can't start an expression. - return !isStartOfExpression(); + // We favor the type argument list interpretation when it is immediately followed by + // a line break, a binary operator, or something that can't start an expression. + return scanner.hasPrecedingLineBreak() || isBinaryOperator() || !isStartOfExpression(); } function parsePrimaryExpression(): PrimaryExpression { diff --git a/tests/baselines/reference/instantiationExpressionErrors.errors.txt b/tests/baselines/reference/instantiationExpressionErrors.errors.txt index 5b60983d594dc..2745416807fc8 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.errors.txt +++ b/tests/baselines/reference/instantiationExpressionErrors.errors.txt @@ -6,11 +6,15 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(19,24): error TS2635: Type '{ (): number; g(): U; }' has no signatures for which the type argument list is applicable. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(23,23): error TS1005: '(' expected. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(26,24): error TS2558: Expected 0 type arguments, but got 1. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(31,2): error TS2554: Expected 0 arguments, but got 1. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(35,12): error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(39,2): error TS2554: Expected 0 arguments, but got 1. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(43,12): error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(44,12): error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(44,12): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(45,12): error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. +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 (10 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (14 errors) ==== declare let f: { (): T, g(): U }; // Type arguments in member expressions @@ -54,6 +58,14 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr ~~~~~~ !!! error TS2558: Expected 0 type arguments, but got 1. + // Instantiation expression and binary operators + + declare let g: ((x: T) => T) | undefined; + + const c1 = g || ((x: string) => x); + const c2 = g ?? ((x: string) => x); + const c3 = g && ((x: string) => x); + // Parsed as function call, even though this differs from JavaScript const x1 = f @@ -61,20 +73,71 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr ~~~~ !!! error TS2554: Expected 0 arguments, but got 1. - // Parsed as relational expression + // Parsed as relational expressions - const x2 = f - ~~~~~~ + const r1 = f < true > true; + ~~~~~~~~ !!! error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. - true; + const r2 = f < true > +1; + ~~~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. + ~~~~~~~~~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. + const r3 = f < true > -1; + ~~~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. + ~~~~~~~~~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. - // Parsed as instantiation expression + // All of the following are parsed as instantiation expressions - const x3 = f; + const x2 = f true; - // Parsed as instantiation expression + const x3 = f; + true; const x4 = f if (true) {} + + const x5 = f + let yy = 0; + + const x6 = f + interface I {} + + let x10 = f + this.bar() + + let x11 = f + function bar() {} + + let x12 = f + class C {} + + let x13 = f + bar() + + let x14 = f + void bar() + + class C1 { + static specialFoo = f + static bar = 123 + } + + class C2 { + public specialFoo = f + public bar = 123 + } + + class C3 { + private specialFoo = f + private bar = 123 + } + + class C4 { + protected specialFoo = f + protected bar = 123 + } \ No newline at end of file diff --git a/tests/baselines/reference/instantiationExpressionErrors.js b/tests/baselines/reference/instantiationExpressionErrors.js index 9f6b17f13787a..c29046d913e85 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.js +++ b/tests/baselines/reference/instantiationExpressionErrors.js @@ -26,30 +26,81 @@ const b2 = f?.(); const b3 = f?.(); const b4 = f?.(); // Error, expected no type arguments +// Instantiation expression and binary operators + +declare let g: ((x: T) => T) | undefined; + +const c1 = g || ((x: string) => x); +const c2 = g ?? ((x: string) => x); +const c3 = g && ((x: string) => x); + // Parsed as function call, even though this differs from JavaScript const x1 = f (true); -// Parsed as relational expression +// Parsed as relational expressions + +const r1 = f < true > true; +const r2 = f < true > +1; +const r3 = f < true > -1; + +// All of the following are parsed as instantiation expressions const x2 = f true; -// Parsed as instantiation expression - const x3 = f; true; -// Parsed as instantiation expression - const x4 = f if (true) {} + +const x5 = f +let yy = 0; + +const x6 = f +interface I {} + +let x10 = f +this.bar() + +let x11 = f +function bar() {} + +let x12 = f +class C {} + +let x13 = f +bar() + +let x14 = f +void bar() + +class C1 { + static specialFoo = f + static bar = 123 +} + +class C2 { + public specialFoo = f + public bar = 123 +} + +class C3 { + private specialFoo = f + private bar = 123 +} + +class C4 { + protected specialFoo = f + protected bar = 123 +} //// [instantiationExpressionErrors.js] "use strict"; -var _a, _b; +var _a, _b, _c; // Type arguments in member expressions var a1 = (f); // { (): number; g(): U; } var a2 = (f.g); // () => number @@ -67,17 +118,67 @@ var b1 = f === null || f === void 0 ? void 0 : f(); // Error, `(` expected var b2 = f === null || f === void 0 ? void 0 : f(); var b3 = (_a = (f)) === null || _a === void 0 ? void 0 : _a(); var b4 = (_b = (f)) === null || _b === void 0 ? void 0 : _b(); // Error, expected no type arguments +var c1 = (g) || (function (x) { return x; }); +var c2 = (_c = (g)) !== null && _c !== void 0 ? _c : (function (x) { return x; }); +var c3 = (g) && (function (x) { return x; }); // Parsed as function call, even though this differs from JavaScript var x1 = f(true); -// Parsed as relational expression -var x2 = f < true > - true; -// Parsed as instantiation expression +// Parsed as relational expressions +var r1 = f < true > true; +var r2 = f < true > +1; +var r3 = f < true > -1; +// All of the following are parsed as instantiation expressions +var x2 = (f); +true; var x3 = (f); true; -// Parsed as instantiation expression var x4 = (f); if (true) { } +var x5 = (f); +var yy = 0; +var x6 = (f); +var x10 = (f); +this.bar(); +var x11 = (f); +function bar() { } +var x12 = (f); +var C = /** @class */ (function () { + function C() { + } + return C; +}()); +var x13 = (f); +bar(); +var x14 = (f); +void bar(); +var C1 = /** @class */ (function () { + function C1() { + } + C1.specialFoo = (f); + C1.bar = 123; + return C1; +}()); +var C2 = /** @class */ (function () { + function C2() { + this.specialFoo = (f); + this.bar = 123; + } + return C2; +}()); +var C3 = /** @class */ (function () { + function C3() { + this.specialFoo = (f); + this.bar = 123; + } + return C3; +}()); +var C4 = /** @class */ (function () { + function C4() { + this.specialFoo = (f); + this.bar = 123; + } + return C4; +}()); //// [instantiationExpressionErrors.d.ts] @@ -103,8 +204,18 @@ declare const b1: number; declare const b2: number; declare const b3: number; declare const b4: number; +declare let g: ((x: T) => T) | undefined; +declare const c1: (x: string) => string; +declare const c2: (x: string) => string; +declare const c3: ((x: string) => string) | undefined; declare const x1: true; -declare const x2: boolean; +declare const r1: boolean; +declare const r2: boolean; +declare const r3: boolean; +declare const x2: { + (): true; + g(): U; +}; declare const x3: { (): true; g(): U; @@ -113,3 +224,62 @@ declare const x4: { (): true; g(): U; }; +declare const x5: { + (): true; + g(): U; +}; +declare let yy: number; +declare const x6: { + (): true; + g(): U; +}; +interface I { +} +declare let x10: { + (): true; + g(): U; +}; +declare let x11: { + (): true; + g(): U; +}; +declare function bar(): void; +declare let x12: { + (): true; + g(): U; +}; +declare class C { +} +declare let x13: { + (): true; + g(): U; +}; +declare let x14: { + (): true; + g(): U; +}; +declare class C1 { + static specialFoo: { + (): string; + g(): U; + }; + static bar: number; +} +declare class C2 { + specialFoo: { + (): string; + g(): U; + }; + bar: number; +} +declare class C3 { + private specialFoo; + private bar; +} +declare class C4 { + protected specialFoo: { + (): string; + g(): U; + }; + protected bar: number; +} diff --git a/tests/baselines/reference/instantiationExpressionErrors.symbols b/tests/baselines/reference/instantiationExpressionErrors.symbols index dc1e6d5d64b3c..86f97631ea8db 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.symbols +++ b/tests/baselines/reference/instantiationExpressionErrors.symbols @@ -75,35 +75,167 @@ const b4 = f?.(); // Error, expected no type arguments >b4 : Symbol(b4, Decl(instantiationExpressionErrors.ts, 25, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +// Instantiation expression and binary operators + +declare let g: ((x: T) => T) | undefined; +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 29, 11)) +>T : Symbol(T, Decl(instantiationExpressionErrors.ts, 29, 17)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 29, 20)) +>T : Symbol(T, Decl(instantiationExpressionErrors.ts, 29, 17)) +>T : Symbol(T, Decl(instantiationExpressionErrors.ts, 29, 17)) + +const c1 = g || ((x: string) => x); +>c1 : Symbol(c1, Decl(instantiationExpressionErrors.ts, 31, 5)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 29, 11)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 31, 26)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 31, 26)) + +const c2 = g ?? ((x: string) => x); +>c2 : Symbol(c2, Decl(instantiationExpressionErrors.ts, 32, 5)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 29, 11)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 32, 26)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 32, 26)) + +const c3 = g && ((x: string) => x); +>c3 : Symbol(c3, Decl(instantiationExpressionErrors.ts, 33, 5)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 29, 11)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 33, 26)) +>x : Symbol(x, Decl(instantiationExpressionErrors.ts, 33, 26)) + // Parsed as function call, even though this differs from JavaScript const x1 = f ->x1 : Symbol(x1, Decl(instantiationExpressionErrors.ts, 29, 5)) +>x1 : Symbol(x1, Decl(instantiationExpressionErrors.ts, 37, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) (true); -// Parsed as relational expression +// Parsed as relational expressions + +const r1 = f < true > true; +>r1 : Symbol(r1, Decl(instantiationExpressionErrors.ts, 42, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const r2 = f < true > +1; +>r2 : Symbol(r2, Decl(instantiationExpressionErrors.ts, 43, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const r3 = f < true > -1; +>r3 : Symbol(r3, Decl(instantiationExpressionErrors.ts, 44, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +// All of the following are parsed as instantiation expressions const x2 = f ->x2 : Symbol(x2, Decl(instantiationExpressionErrors.ts, 34, 5)) +>x2 : Symbol(x2, Decl(instantiationExpressionErrors.ts, 48, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) true; -// Parsed as instantiation expression - const x3 = f; ->x3 : Symbol(x3, Decl(instantiationExpressionErrors.ts, 39, 5)) +>x3 : Symbol(x3, Decl(instantiationExpressionErrors.ts, 51, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) true; -// Parsed as instantiation expression - const x4 = f ->x4 : Symbol(x4, Decl(instantiationExpressionErrors.ts, 44, 5)) +>x4 : Symbol(x4, Decl(instantiationExpressionErrors.ts, 54, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) if (true) {} +const x5 = f +>x5 : Symbol(x5, Decl(instantiationExpressionErrors.ts, 57, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +let yy = 0; +>yy : Symbol(yy, Decl(instantiationExpressionErrors.ts, 58, 3)) + +const x6 = f +>x6 : Symbol(x6, Decl(instantiationExpressionErrors.ts, 60, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +interface I {} +>I : Symbol(I, Decl(instantiationExpressionErrors.ts, 60, 18)) + +let x10 = f +>x10 : Symbol(x10, Decl(instantiationExpressionErrors.ts, 63, 3)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +this.bar() +>this.bar : Symbol(bar, Decl(instantiationExpressionErrors.ts, 66, 17)) +>this : Symbol(globalThis) +>bar : Symbol(bar, Decl(instantiationExpressionErrors.ts, 66, 17)) + +let x11 = f +>x11 : Symbol(x11, Decl(instantiationExpressionErrors.ts, 66, 3)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +function bar() {} +>bar : Symbol(bar, Decl(instantiationExpressionErrors.ts, 66, 17)) + +let x12 = f +>x12 : Symbol(x12, Decl(instantiationExpressionErrors.ts, 69, 3)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +class C {} +>C : Symbol(C, Decl(instantiationExpressionErrors.ts, 69, 17)) + +let x13 = f +>x13 : Symbol(x13, Decl(instantiationExpressionErrors.ts, 72, 3)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +bar() +>bar : Symbol(bar, Decl(instantiationExpressionErrors.ts, 66, 17)) + +let x14 = f +>x14 : Symbol(x14, Decl(instantiationExpressionErrors.ts, 75, 3)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +void bar() +>bar : Symbol(bar, Decl(instantiationExpressionErrors.ts, 66, 17)) + +class C1 { +>C1 : Symbol(C1, Decl(instantiationExpressionErrors.ts, 76, 10)) + + static specialFoo = f +>specialFoo : Symbol(C1.specialFoo, Decl(instantiationExpressionErrors.ts, 78, 10)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + + static bar = 123 +>bar : Symbol(C1.bar, Decl(instantiationExpressionErrors.ts, 79, 33)) +} + +class C2 { +>C2 : Symbol(C2, Decl(instantiationExpressionErrors.ts, 81, 1)) + + public specialFoo = f +>specialFoo : Symbol(C2.specialFoo, Decl(instantiationExpressionErrors.ts, 83, 10)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + + public bar = 123 +>bar : Symbol(C2.bar, Decl(instantiationExpressionErrors.ts, 84, 33)) +} + +class C3 { +>C3 : Symbol(C3, Decl(instantiationExpressionErrors.ts, 86, 1)) + + private specialFoo = f +>specialFoo : Symbol(C3.specialFoo, Decl(instantiationExpressionErrors.ts, 88, 10)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + + private bar = 123 +>bar : Symbol(C3.bar, Decl(instantiationExpressionErrors.ts, 89, 34)) +} + +class C4 { +>C4 : Symbol(C4, Decl(instantiationExpressionErrors.ts, 91, 1)) + + protected specialFoo = f +>specialFoo : Symbol(C4.specialFoo, Decl(instantiationExpressionErrors.ts, 93, 10)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + + protected bar = 123 +>bar : Symbol(C4.bar, Decl(instantiationExpressionErrors.ts, 94, 36)) +} + diff --git a/tests/baselines/reference/instantiationExpressionErrors.types b/tests/baselines/reference/instantiationExpressionErrors.types index c2de6b5720ec1..9b77ad997aee0 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.types +++ b/tests/baselines/reference/instantiationExpressionErrors.types @@ -100,6 +100,42 @@ const b4 = f?.(); // Error, expected no type arguments >f : { (): number; g(): U; } >f : { (): T; g(): U; } +// Instantiation expression and binary operators + +declare let g: ((x: T) => T) | undefined; +>g : ((x: T) => T) | undefined +>x : T + +const c1 = g || ((x: string) => x); +>c1 : (x: string) => string +>g || ((x: string) => x) : (x: string) => string +>g : ((x: string) => string) | undefined +>g : ((x: T) => T) | undefined +>((x: string) => x) : (x: string) => string +>(x: string) => x : (x: string) => string +>x : string +>x : string + +const c2 = g ?? ((x: string) => x); +>c2 : (x: string) => string +>g ?? ((x: string) => x) : (x: string) => string +>g : ((x: string) => string) | undefined +>g : ((x: T) => T) | undefined +>((x: string) => x) : (x: string) => string +>(x: string) => x : (x: string) => string +>x : string +>x : string + +const c3 = g && ((x: string) => x); +>c3 : ((x: string) => string) | undefined +>g && ((x: string) => x) : ((x: string) => string) | undefined +>g : ((x: string) => string) | undefined +>g : ((x: T) => T) | undefined +>((x: string) => x) : (x: string) => string +>(x: string) => x : (x: string) => string +>x : string +>x : string + // Parsed as function call, even though this differs from JavaScript const x1 = f @@ -111,20 +147,45 @@ const x1 = f (true); >true : true -// Parsed as relational expression +// Parsed as relational expressions + +const r1 = f < true > true; +>r1 : boolean +>f < true > true : boolean +>f < true : boolean +>f : { (): T; g(): U; } +>true : true +>true : true + +const r2 = f < true > +1; +>r2 : boolean +>f < true > +1 : boolean +>f < true : boolean +>f : { (): T; g(): U; } +>true : true +>+1 : 1 +>1 : 1 + +const r3 = f < true > -1; +>r3 : boolean +>f < true > -1 : boolean +>f < true : boolean +>f : { (): T; g(): U; } +>true : true +>-1 : -1 +>1 : 1 + +// All of the following are parsed as instantiation expressions const x2 = f ->x2 : boolean ->ftrue : boolean ->fx2 : { (): true; g(): U; } +>f : { (): true; g(): U; } >f : { (): T; g(): U; } >true : true true; >true : true -// Parsed as instantiation expression - const x3 = f; >x3 : { (): true; g(): U; } >f : { (): true; g(): U; } @@ -134,8 +195,6 @@ const x3 = f; true; >true : true -// Parsed as instantiation expression - const x4 = f >x4 : { (): true; g(): U; } >f : { (): true; g(): U; } @@ -145,3 +204,124 @@ const x4 = f if (true) {} >true : true +const x5 = f +>x5 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +let yy = 0; +>yy : number +>0 : 0 + +const x6 = f +>x6 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +interface I {} + +let x10 = f +>x10 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +this.bar() +>this.bar() : void +>this.bar : () => void +>this : typeof globalThis +>bar : () => void + +let x11 = f +>x11 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +function bar() {} +>bar : () => void + +let x12 = f +>x12 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +class C {} +>C : C + +let x13 = f +>x13 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +bar() +>bar() : void +>bar : () => void + +let x14 = f +>x14 : { (): true; g(): U; } +>f : { (): true; g(): U; } +>f : { (): T; g(): U; } +>true : true + +void bar() +>void bar() : undefined +>bar() : void +>bar : () => void + +class C1 { +>C1 : C1 + + static specialFoo = f +>specialFoo : { (): string; g(): U; } +>f : { (): string; g(): U; } +>f : { (): T; g(): U; } + + static bar = 123 +>bar : number +>123 : 123 +} + +class C2 { +>C2 : C2 + + public specialFoo = f +>specialFoo : { (): string; g(): U; } +>f : { (): string; g(): U; } +>f : { (): T; g(): U; } + + public bar = 123 +>bar : number +>123 : 123 +} + +class C3 { +>C3 : C3 + + private specialFoo = f +>specialFoo : { (): string; g(): U; } +>f : { (): string; g(): U; } +>f : { (): T; g(): U; } + + private bar = 123 +>bar : number +>123 : 123 +} + +class C4 { +>C4 : C4 + + protected specialFoo = f +>specialFoo : { (): string; g(): U; } +>f : { (): string; g(): U; } +>f : { (): T; g(): U; } + + protected bar = 123 +>bar : number +>123 : 123 +} + diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts index 1a9377ae9c5c8..83e8f392830c3 100644 --- a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts @@ -28,22 +28,73 @@ const b2 = f?.(); const b3 = f?.(); const b4 = f?.(); // Error, expected no type arguments +// Instantiation expression and binary operators + +declare let g: ((x: T) => T) | undefined; + +const c1 = g || ((x: string) => x); +const c2 = g ?? ((x: string) => x); +const c3 = g && ((x: string) => x); + // Parsed as function call, even though this differs from JavaScript const x1 = f (true); -// Parsed as relational expression +// Parsed as relational expressions + +const r1 = f < true > true; +const r2 = f < true > +1; +const r3 = f < true > -1; + +// All of the following are parsed as instantiation expressions const x2 = f true; -// Parsed as instantiation expression - const x3 = f; true; -// Parsed as instantiation expression - const x4 = f if (true) {} + +const x5 = f +let yy = 0; + +const x6 = f +interface I {} + +let x10 = f +this.bar() + +let x11 = f +function bar() {} + +let x12 = f +class C {} + +let x13 = f +bar() + +let x14 = f +void bar() + +class C1 { + static specialFoo = f + static bar = 123 +} + +class C2 { + public specialFoo = f + public bar = 123 +} + +class C3 { + private specialFoo = f + private bar = 123 +} + +class C4 { + protected specialFoo = f + protected bar = 123 +} diff --git a/tests/cases/fourslash/completionListInUnclosedTypeArguments.ts b/tests/cases/fourslash/completionListInUnclosedTypeArguments.ts index 8a100a9616e3d..5bc1a2d08132a 100644 --- a/tests/cases/fourslash/completionListInUnclosedTypeArguments.ts +++ b/tests/cases/fourslash/completionListInUnclosedTypeArguments.ts @@ -13,8 +13,8 @@ ////f2 -////f2 +////f2 +////f2 ////f2(); //// ////f2