From ddf4d3a421d8a2de0aa740d0f96958d9eb8ade7c Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 22 Feb 2021 12:14:41 -0800 Subject: [PATCH 1/2] Never-reducing intersections are not untyped function call targets --- src/compiler/checker.ts | 2 +- .../reference/neverIntersectionNotCallable.errors.txt | 11 +++++++++++ .../reference/neverIntersectionNotCallable.js | 7 +++++++ .../reference/neverIntersectionNotCallable.symbols | 10 ++++++++++ .../reference/neverIntersectionNotCallable.types | 11 +++++++++++ .../types/never/neverIntersectionNotCallable.ts | 2 ++ 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/neverIntersectionNotCallable.errors.txt create mode 100644 tests/baselines/reference/neverIntersectionNotCallable.js create mode 100644 tests/baselines/reference/neverIntersectionNotCallable.symbols create mode 100644 tests/baselines/reference/neverIntersectionNotCallable.types create mode 100644 tests/cases/conformance/types/never/neverIntersectionNotCallable.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c7fab735856e..795189f4a109a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28359,7 +28359,7 @@ namespace ts { function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number): boolean { // We exclude union types because we may have a union of function types that happen to have no common signatures. return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & TypeFlags.TypeParameter) || - !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType); + !numCallSignatures && !numConstructSignatures && !(getReducedType(apparentFuncType).flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType); } function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { diff --git a/tests/baselines/reference/neverIntersectionNotCallable.errors.txt b/tests/baselines/reference/neverIntersectionNotCallable.errors.txt new file mode 100644 index 0000000000000..5ae3d35a692aa --- /dev/null +++ b/tests/baselines/reference/neverIntersectionNotCallable.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/types/never/neverIntersectionNotCallable.ts(2,1): error TS2349: This expression is not callable. + Type 'never' has no call signatures. + + +==== tests/cases/conformance/types/never/neverIntersectionNotCallable.ts (1 errors) ==== + declare const f: { (x: string): number, a: "" } & { a: number } + f() + ~ +!!! error TS2349: This expression is not callable. +!!! error TS2349: Type 'never' has no call signatures. + \ No newline at end of file diff --git a/tests/baselines/reference/neverIntersectionNotCallable.js b/tests/baselines/reference/neverIntersectionNotCallable.js new file mode 100644 index 0000000000000..b06cd75ee4398 --- /dev/null +++ b/tests/baselines/reference/neverIntersectionNotCallable.js @@ -0,0 +1,7 @@ +//// [neverIntersectionNotCallable.ts] +declare const f: { (x: string): number, a: "" } & { a: number } +f() + + +//// [neverIntersectionNotCallable.js] +f(); diff --git a/tests/baselines/reference/neverIntersectionNotCallable.symbols b/tests/baselines/reference/neverIntersectionNotCallable.symbols new file mode 100644 index 0000000000000..129b73cb84a99 --- /dev/null +++ b/tests/baselines/reference/neverIntersectionNotCallable.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/types/never/neverIntersectionNotCallable.ts === +declare const f: { (x: string): number, a: "" } & { a: number } +>f : Symbol(f, Decl(neverIntersectionNotCallable.ts, 0, 13)) +>x : Symbol(x, Decl(neverIntersectionNotCallable.ts, 0, 20)) +>a : Symbol(a, Decl(neverIntersectionNotCallable.ts, 0, 39)) +>a : Symbol(a, Decl(neverIntersectionNotCallable.ts, 0, 51)) + +f() +>f : Symbol(f, Decl(neverIntersectionNotCallable.ts, 0, 13)) + diff --git a/tests/baselines/reference/neverIntersectionNotCallable.types b/tests/baselines/reference/neverIntersectionNotCallable.types new file mode 100644 index 0000000000000..1225532a5c406 --- /dev/null +++ b/tests/baselines/reference/neverIntersectionNotCallable.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/types/never/neverIntersectionNotCallable.ts === +declare const f: { (x: string): number, a: "" } & { a: number } +>f : never +>x : string +>a : "" +>a : number + +f() +>f() : any +>f : never + diff --git a/tests/cases/conformance/types/never/neverIntersectionNotCallable.ts b/tests/cases/conformance/types/never/neverIntersectionNotCallable.ts new file mode 100644 index 0000000000000..1d38fdebde9b5 --- /dev/null +++ b/tests/cases/conformance/types/never/neverIntersectionNotCallable.ts @@ -0,0 +1,2 @@ +declare const f: { (x: string): number, a: "" } & { a: number } +f() From 5015a515471cd8b4f7f9186c7f8c15ae0de02b7d Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 22 Feb 2021 12:16:30 -0800 Subject: [PATCH 2/2] =?UTF-8?q?Don=E2=80=99t=20attempt=20to=20reduce=20uni?= =?UTF-8?q?on=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 795189f4a109a..a64d6ebd1e786 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28359,7 +28359,7 @@ namespace ts { function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number): boolean { // We exclude union types because we may have a union of function types that happen to have no common signatures. return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & TypeFlags.TypeParameter) || - !numCallSignatures && !numConstructSignatures && !(getReducedType(apparentFuncType).flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType); + !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & TypeFlags.Union) && !(getReducedType(apparentFuncType).flags & TypeFlags.Never) && isTypeAssignableTo(funcType, globalFunctionType); } function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {