Skip to content

Commit

Permalink
Merge pull request #31560 from andrewbranch/bug/31485
Browse files Browse the repository at this point in the history
Fix crash when creating a union signature from signatures that do and don’t have `this` types
  • Loading branch information
andrewbranch committed May 24, 2019
2 parents 9380b9f + 300cbef commit a06ab85
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/compiler/checker.ts
Expand Up @@ -7056,10 +7056,10 @@ namespace ts {
// Union the result types when more than one signature matches
if (unionSignatures.length > 1) {
let thisParameter = signature.thisParameter;
if (forEach(unionSignatures, sig => sig.thisParameter)) {
// TODO: GH#18217 We tested that *some* has thisParameter and now act as if *all* do
const firstThisParameterOfUnionSignatures = forEach(unionSignatures, sig => sig.thisParameter);
if (firstThisParameterOfUnionSignatures) {
const thisType = getUnionType(map(unionSignatures, sig => sig.thisParameter ? getTypeOfSymbol(sig.thisParameter) : anyType), UnionReduction.Subtype);
thisParameter = createSymbolWithType(signature.thisParameter!, thisType);
thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType);
}
s = createUnionSignature(signature, unionSignatures);
s.thisParameter = thisParameter;
Expand Down
17 changes: 17 additions & 0 deletions tests/baselines/reference/unionTypeCallSignatures5.js
@@ -0,0 +1,17 @@
//// [unionTypeCallSignatures5.ts]
// #31485
interface A {
(this: void, b?: number): void;
}
interface B {
(this: number, b?: number): void;
}
interface C {
(i: number): void;
}
declare const fn: A | B | C;
fn(0);


//// [unionTypeCallSignatures5.js]
fn(0);
31 changes: 31 additions & 0 deletions tests/baselines/reference/unionTypeCallSignatures5.symbols
@@ -0,0 +1,31 @@
=== tests/cases/conformance/types/union/unionTypeCallSignatures5.ts ===
// #31485
interface A {
>A : Symbol(A, Decl(unionTypeCallSignatures5.ts, 0, 0))

(this: void, b?: number): void;
>this : Symbol(this, Decl(unionTypeCallSignatures5.ts, 2, 3))
>b : Symbol(b, Decl(unionTypeCallSignatures5.ts, 2, 14))
}
interface B {
>B : Symbol(B, Decl(unionTypeCallSignatures5.ts, 3, 1))

(this: number, b?: number): void;
>this : Symbol(this, Decl(unionTypeCallSignatures5.ts, 5, 3))
>b : Symbol(b, Decl(unionTypeCallSignatures5.ts, 5, 16))
}
interface C {
>C : Symbol(C, Decl(unionTypeCallSignatures5.ts, 6, 1))

(i: number): void;
>i : Symbol(i, Decl(unionTypeCallSignatures5.ts, 8, 3))
}
declare const fn: A | B | C;
>fn : Symbol(fn, Decl(unionTypeCallSignatures5.ts, 10, 13))
>A : Symbol(A, Decl(unionTypeCallSignatures5.ts, 0, 0))
>B : Symbol(B, Decl(unionTypeCallSignatures5.ts, 3, 1))
>C : Symbol(C, Decl(unionTypeCallSignatures5.ts, 6, 1))

fn(0);
>fn : Symbol(fn, Decl(unionTypeCallSignatures5.ts, 10, 13))

24 changes: 24 additions & 0 deletions tests/baselines/reference/unionTypeCallSignatures5.types
@@ -0,0 +1,24 @@
=== tests/cases/conformance/types/union/unionTypeCallSignatures5.ts ===
// #31485
interface A {
(this: void, b?: number): void;
>this : void
>b : number
}
interface B {
(this: number, b?: number): void;
>this : number
>b : number
}
interface C {
(i: number): void;
>i : number
}
declare const fn: A | B | C;
>fn : A | B | C

fn(0);
>fn(0) : void
>fn : A | B | C
>0 : 0

12 changes: 12 additions & 0 deletions tests/cases/conformance/types/union/unionTypeCallSignatures5.ts
@@ -0,0 +1,12 @@
// #31485
interface A {
(this: void, b?: number): void;
}
interface B {
(this: number, b?: number): void;
}
interface C {
(i: number): void;
}
declare const fn: A | B | C;
fn(0);

0 comments on commit a06ab85

Please sign in to comment.