diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a4cb8f9d8a5ee..dfb7ec0512883 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2016,6 +2016,8 @@ namespace ts { case SyntaxKind.AwaitExpression: case SyntaxKind.MetaProperty: return true; + case SyntaxKind.ExpressionWithTypeArguments: + return !isHeritageClause(node.parent); case SyntaxKind.QualifiedName: while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; diff --git a/src/testRunner/unittests/publicApi.ts b/src/testRunner/unittests/publicApi.ts index 4bfce8288f500..00d8994520f54 100644 --- a/src/testRunner/unittests/publicApi.ts +++ b/src/testRunner/unittests/publicApi.ts @@ -131,6 +131,30 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => { assert.equal(type.flags, ts.TypeFlags.Any); }); + it("works on ExpressionWithTypeArguments", () => { + const content = ` + function fn(value: T) { + return { value }; + } + const foo = fn; + `; + const host = new fakes.CompilerHost(vfs.createFromFileSystem( + Harness.IO, + /*ignoreCase*/ true, + { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); + + const program = ts.createProgram({ + host, + rootNames: ["/file.ts"], + options: { noLib: true } + }); + + const checker = program.getTypeChecker(); + const file = program.getSourceFile("/file.ts")!; + const [declaration] = (ts.findLast(file.statements, ts.isVariableStatement) as ts.VariableStatement).declarationList.declarations; + assert.equal(checker.getTypeAtLocation(declaration.initializer!).flags, ts.TypeFlags.Object); + }); + it("returns an errorType for VariableDeclaration with BindingPattern name", () => { const content = "const foo = [1];\n" + "const [a] = foo;"; diff --git a/tests/baselines/reference/genericCallWithoutArgs.types b/tests/baselines/reference/genericCallWithoutArgs.types index 82c32a2ad0444..6d4969a83ee7e 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.types +++ b/tests/baselines/reference/genericCallWithoutArgs.types @@ -7,6 +7,7 @@ function f(x: X, y: Y) { f. >f. : any +>f : (x: number, y: string) => void >f : (x: X, y: Y) => void > : any diff --git a/tests/baselines/reference/importWithTypeArguments.types b/tests/baselines/reference/importWithTypeArguments.types index 442b3cc9ed993..2998bd6f20e3b 100644 --- a/tests/baselines/reference/importWithTypeArguments.types +++ b/tests/baselines/reference/importWithTypeArguments.types @@ -1,5 +1,8 @@ === tests/cases/conformance/types/import/importWithTypeArguments.ts === import +>import : any + const a = import >a : any +>import : any diff --git a/tests/baselines/reference/instantiationExpressionErrors.types b/tests/baselines/reference/instantiationExpressionErrors.types index 334cb69865e01..c2de6b5720ec1 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.types +++ b/tests/baselines/reference/instantiationExpressionErrors.types @@ -7,10 +7,12 @@ declare let f: { (): T, g(): U }; const a1 = f; // { (): number; g(): U; } >a1 : { (): number; g(): U; } +>f : { (): number; g(): U; } >f : { (): T; g(): U; } const a2 = f.g; // () => number >a2 : () => number +>f.g : () => number >f.g : () => U >f : { (): T; g(): U; } >g : () => U @@ -18,17 +20,21 @@ const a2 = f.g; // () => number const a3 = f.g; // () => U >a3 : () => U >f.g : () => U +>f : { (): number; g(): U; } >f : { (): T; g(): U; } >g : () => U const a4 = f.g; // () => number >a4 : () => number +>f.g : () => number >f.g : () => U +>f : { (): number; g(): U; } >f : { (): T; g(): U; } >g : () => U const a5 = f['g']; // () => number >a5 : () => number +>f['g'] : () => number >f['g'] : () => U >f : { (): T; g(): U; } >'g' : "g" @@ -48,6 +54,7 @@ const a7 = (f)['g']; >a7 : () => U >(f)['g'] : () => U >(f) : { (): number; g(): U; } +>f : { (): number; g(): U; } >f : { (): T; g(): U; } >'g' : "g" @@ -64,7 +71,9 @@ const a8 = f; // Relational operator error const a9 = (f); // Error, no applicable signatures >a9 : { g(): U; } +>(f) : { g(): U; } >(f) : { (): number; g(): U; } +>f : { (): number; g(): U; } >f : { (): T; g(): U; } // Type arguments with `?.` token @@ -82,11 +91,13 @@ const b2 = f?.(); const b3 = f?.(); >b3 : number >f?.() : number +>f : { (): number; g(): U; } >f : { (): T; g(): U; } const b4 = f?.(); // Error, expected no type arguments >b4 : number >f?.() : number +>f : { (): number; g(): U; } >f : { (): T; g(): U; } // Parsed as function call, even though this differs from JavaScript @@ -116,6 +127,7 @@ true; const x3 = f; >x3 : { (): true; g(): U; } +>f : { (): true; g(): U; } >f : { (): T; g(): U; } >true : true @@ -126,6 +138,7 @@ true; const x4 = f >x4 : { (): true; g(): U; } +>f : { (): true; g(): U; } >f : { (): T; g(): U; } >true : true diff --git a/tests/baselines/reference/instantiationExpressions.types b/tests/baselines/reference/instantiationExpressions.types index bb35bc036a14a..75fe72fc441bc 100644 --- a/tests/baselines/reference/instantiationExpressions.types +++ b/tests/baselines/reference/instantiationExpressions.types @@ -17,18 +17,22 @@ function f1() { let f0 = fx<>; // Error >f0 : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>fx<> : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } let f1 = fx; // { (x: string): string; (x: string, n: number): string; } >f1 : { (x: string): string; (x: string, n: number): string; } +>fx : { (x: string): string; (x: string, n: number): string; } >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } let f2 = fx; // (t: [string, number]) => [string, number] >f2 : (t: [string, number]) => [string, number] +>fx : (t: [string, number]) => [string, number] >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } let f3 = fx; // Error >f3 : {} +>fx : {} >fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } } @@ -53,14 +57,17 @@ function f2() { const A0 = Array<>; // Error >A0 : ArrayConstructor +>Array<> : ArrayConstructor >Array : ArrayConstructor const A1 = Array; // new (...) => string[] >A1 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } >Array : ArrayConstructor const A2 = Array; // Error >A2 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : { isArray(arg: any): arg is any[]; readonly prototype: any[]; } >Array : ArrayConstructor } @@ -92,10 +99,12 @@ function f3() { let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } >c1 : { new (x: string): C; prototype: C; f(x: U): U[]; } +>C : { new (x: string): C; prototype: C; f(x: U): U[]; } >C : typeof C let f1 = C.f; // (x: string) => string[] >f1 : (x: string) => string[] +>C.f : (x: string) => string[] >C.f : (x: U) => U[] >C : typeof C >f : (x: U) => U[] @@ -110,6 +119,7 @@ function f10(f: { (a: T): T, (a: U, b: number): U[] }) { let fs = f; // { (a: string): string; (a: string, b: number): string[]; } >fs : { (a: string): string; (a: string, b: number): string[]; } +>f : { (a: string): string; (a: string, b: number): string[]; } >f : { (a: T): T; (a: U, b: number): U[]; } } @@ -122,6 +132,7 @@ function f11(f: { (a: T): T, (a: string, b: number): string[] }) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : { (a: T): T; (a: string, b: number): string[]; } } @@ -133,6 +144,7 @@ function f12(f: { (a: T): T, x: string }) { let fs = f; // { (a: string): string; x: string; } >fs : { (a: string): string; x: string; } +>f : { (a: string): string; x: string; } >f : { (a: T): T; x: string; } } @@ -144,6 +156,7 @@ function f13(f: { x: string, y: string }) { let fs = f; // Error, no applicable signatures >fs : { x: string; y: string; } +>f : { x: string; y: string; } >f : { x: string; y: string; } } @@ -156,6 +169,7 @@ function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } >fs : { new (a: string): string; new (a: string, b: number): string[]; } +>f : { new (a: string): string; new (a: string, b: number): string[]; } >f : { new (a: T): T; new (a: U, b: number): U[]; } } @@ -168,6 +182,7 @@ function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } >fs : { (a: string, b: number): string[]; new (a: string): string; } +>f : { (a: string, b: number): string[]; new (a: string): string; } >f : { (a: U, b: number): U[]; new (a: T): T; } } @@ -180,6 +195,7 @@ function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { let fs = f; // new (a: string) => string >fs : new (a: string) => string +>f : new (a: string) => string >f : { (a: string, b: number): string[]; new (a: T): T; } } @@ -192,6 +208,7 @@ function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : { (a: T): T; new (a: string, b: number): string[]; } } @@ -204,6 +221,7 @@ function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) >fs : ((a: string) => string) & ((a: string, b: number) => string[]) +>f : ((a: string) => string) & ((a: string, b: number) => string[]) >f : ((a: T) => T) & ((a: U, b: number) => U[]) } @@ -216,6 +234,7 @@ function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : ((a: T) => T) & ((a: string, b: number) => string[]) } @@ -227,6 +246,7 @@ function f22(f: ((a: T) => T) & { x: string }) { let fs = f; // ((a: string) => string) & { x: string } >fs : ((a: string) => string) & { x: string; } +>f : ((a: string) => string) & { x: string; } >f : ((a: T) => T) & { x: string; } } @@ -238,6 +258,7 @@ function f23(f: { x: string } & { y: string }) { let fs = f; // Error, no applicable signatures >fs : { x: string; } & { y: string; } +>f : { x: string; } & { y: string; } >f : { x: string; } & { y: string; } } @@ -250,6 +271,7 @@ function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) & (new (a: string, b: number) => string[]) +>f : (new (a: string) => string) & (new (a: string, b: number) => string[]) >f : (new (a: T) => T) & (new (a: U, b: number) => U[]) } @@ -262,6 +284,7 @@ function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) & ((a: string, b: number) => string[]) +>f : (new (a: string) => string) & ((a: string, b: number) => string[]) >f : (new (a: T) => T) & ((a: U, b: number) => U[]) } @@ -274,6 +297,7 @@ function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { let fs = f; // new (a: string) => string >fs : new (a: string) => string +>f : new (a: string) => string >f : (new (a: T) => T) & ((a: string, b: number) => string[]) } @@ -286,6 +310,7 @@ function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { let fs = f; // (a: string) => string >fs : (a: string) => string +>f : (a: string) => string >f : ((a: T) => T) & (new (a: string, b: number) => string[]) } @@ -298,6 +323,7 @@ function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) >fs : ((a: string) => string) | ((a: string, b: number) => string[]) +>f : ((a: string) => string) | ((a: string, b: number) => string[]) >f : ((a: T) => T) | ((a: U, b: number) => U[]) } @@ -310,6 +336,7 @@ function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures >fs : ((a: string) => string) | {} +>f : ((a: string) => string) | {} >f : ((a: T) => T) | ((a: string, b: number) => string[]) } @@ -321,6 +348,7 @@ function f32(f: ((a: T) => T) | { x: string }) { let fs = f; // ((a: string) => string) | { x: string } >fs : { x: string; } | ((a: string) => string) +>f : { x: string; } | ((a: string) => string) >f : { x: string; } | ((a: T) => T) } @@ -332,6 +360,7 @@ function f33(f: { x: string } | { y: string }) { let fs = f; // Error, no applicable signatures >fs : { x: string; } | { y: string; } +>f : { x: string; } | { y: string; } >f : { x: string; } | { y: string; } } @@ -344,6 +373,7 @@ function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) | (new (a: string, b: number) => string[]) +>f : (new (a: string) => string) | (new (a: string, b: number) => string[]) >f : (new (a: T) => T) | (new (a: U, b: number) => U[]) } @@ -356,6 +386,7 @@ function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) >fs : (new (a: string) => string) | ((a: string, b: number) => string[]) +>f : (new (a: string) => string) | ((a: string, b: number) => string[]) >f : (new (a: T) => T) | ((a: U, b: number) => U[]) } @@ -368,6 +399,7 @@ function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures >fs : (new (a: string) => string) | {} +>f : (new (a: string) => string) | {} >f : (new (a: T) => T) | ((a: string, b: number) => string[]) } @@ -380,6 +412,7 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures >fs : ((a: string) => string) | {} +>f : ((a: string) => string) | {} >f : ((a: T) => T) | (new (a: string, b: number) => string[]) } @@ -392,6 +425,7 @@ function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ( let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) >fs : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +>f : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) >f : T | U | ((x: C) => C[][]) } diff --git a/tests/baselines/reference/parserMemberAccessExpression1.types b/tests/baselines/reference/parserMemberAccessExpression1.types index 08299f7dfd75f..395f91b2450f3 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.types +++ b/tests/baselines/reference/parserMemberAccessExpression1.types @@ -12,12 +12,14 @@ Foo.Bar(); Foo.Bar(); >Foo.Bar() : any >Foo.Bar : any +>Foo : any >Foo : any >Bar : any Foo.Bar(); >Foo.Bar() : any >Foo.Bar : any +>Foo : any >Foo : any >Bar : any diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types index 2bd59381f8765..b89005fb0ca62 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types @@ -3,6 +3,7 @@ var v = List.makeChild(); >v : any >List.makeChild() : any >List.makeChild : any +>List : any >List : any >makeChild : any