Skip to content

Commit a06ab85

Browse files
authored
Merge pull request #31560 from andrewbranch/bug/31485
Fix crash when creating a union signature from signatures that do and don’t have `this` types
2 parents 9380b9f + 300cbef commit a06ab85

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7056,10 +7056,10 @@ namespace ts {
70567056
// Union the result types when more than one signature matches
70577057
if (unionSignatures.length > 1) {
70587058
let thisParameter = signature.thisParameter;
7059-
if (forEach(unionSignatures, sig => sig.thisParameter)) {
7060-
// TODO: GH#18217 We tested that *some* has thisParameter and now act as if *all* do
7059+
const firstThisParameterOfUnionSignatures = forEach(unionSignatures, sig => sig.thisParameter);
7060+
if (firstThisParameterOfUnionSignatures) {
70617061
const thisType = getUnionType(map(unionSignatures, sig => sig.thisParameter ? getTypeOfSymbol(sig.thisParameter) : anyType), UnionReduction.Subtype);
7062-
thisParameter = createSymbolWithType(signature.thisParameter!, thisType);
7062+
thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType);
70637063
}
70647064
s = createUnionSignature(signature, unionSignatures);
70657065
s.thisParameter = thisParameter;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//// [unionTypeCallSignatures5.ts]
2+
// #31485
3+
interface A {
4+
(this: void, b?: number): void;
5+
}
6+
interface B {
7+
(this: number, b?: number): void;
8+
}
9+
interface C {
10+
(i: number): void;
11+
}
12+
declare const fn: A | B | C;
13+
fn(0);
14+
15+
16+
//// [unionTypeCallSignatures5.js]
17+
fn(0);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/conformance/types/union/unionTypeCallSignatures5.ts ===
2+
// #31485
3+
interface A {
4+
>A : Symbol(A, Decl(unionTypeCallSignatures5.ts, 0, 0))
5+
6+
(this: void, b?: number): void;
7+
>this : Symbol(this, Decl(unionTypeCallSignatures5.ts, 2, 3))
8+
>b : Symbol(b, Decl(unionTypeCallSignatures5.ts, 2, 14))
9+
}
10+
interface B {
11+
>B : Symbol(B, Decl(unionTypeCallSignatures5.ts, 3, 1))
12+
13+
(this: number, b?: number): void;
14+
>this : Symbol(this, Decl(unionTypeCallSignatures5.ts, 5, 3))
15+
>b : Symbol(b, Decl(unionTypeCallSignatures5.ts, 5, 16))
16+
}
17+
interface C {
18+
>C : Symbol(C, Decl(unionTypeCallSignatures5.ts, 6, 1))
19+
20+
(i: number): void;
21+
>i : Symbol(i, Decl(unionTypeCallSignatures5.ts, 8, 3))
22+
}
23+
declare const fn: A | B | C;
24+
>fn : Symbol(fn, Decl(unionTypeCallSignatures5.ts, 10, 13))
25+
>A : Symbol(A, Decl(unionTypeCallSignatures5.ts, 0, 0))
26+
>B : Symbol(B, Decl(unionTypeCallSignatures5.ts, 3, 1))
27+
>C : Symbol(C, Decl(unionTypeCallSignatures5.ts, 6, 1))
28+
29+
fn(0);
30+
>fn : Symbol(fn, Decl(unionTypeCallSignatures5.ts, 10, 13))
31+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/types/union/unionTypeCallSignatures5.ts ===
2+
// #31485
3+
interface A {
4+
(this: void, b?: number): void;
5+
>this : void
6+
>b : number
7+
}
8+
interface B {
9+
(this: number, b?: number): void;
10+
>this : number
11+
>b : number
12+
}
13+
interface C {
14+
(i: number): void;
15+
>i : number
16+
}
17+
declare const fn: A | B | C;
18+
>fn : A | B | C
19+
20+
fn(0);
21+
>fn(0) : void
22+
>fn : A | B | C
23+
>0 : 0
24+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// #31485
2+
interface A {
3+
(this: void, b?: number): void;
4+
}
5+
interface B {
6+
(this: number, b?: number): void;
7+
}
8+
interface C {
9+
(i: number): void;
10+
}
11+
declare const fn: A | B | C;
12+
fn(0);

0 commit comments

Comments
 (0)