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
This commit is contained in:
Andrew Branch 2019-05-24 10:30:47 -07:00 committed by GitHub
commit a06ab8532c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 3 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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))

View File

@ -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

View File

@ -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);