diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8626996b5fbea..5091f5f03063a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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; diff --git a/tests/baselines/reference/unionTypeCallSignatures5.js b/tests/baselines/reference/unionTypeCallSignatures5.js new file mode 100644 index 0000000000000..2e756540d9437 --- /dev/null +++ b/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); diff --git a/tests/baselines/reference/unionTypeCallSignatures5.symbols b/tests/baselines/reference/unionTypeCallSignatures5.symbols new file mode 100644 index 0000000000000..d729dcd7aba6d --- /dev/null +++ b/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)) + diff --git a/tests/baselines/reference/unionTypeCallSignatures5.types b/tests/baselines/reference/unionTypeCallSignatures5.types new file mode 100644 index 0000000000000..53ce4ea655086 --- /dev/null +++ b/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 + diff --git a/tests/cases/conformance/types/union/unionTypeCallSignatures5.ts b/tests/cases/conformance/types/union/unionTypeCallSignatures5.ts new file mode 100644 index 0000000000000..30a5ac031adc1 --- /dev/null +++ b/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);