Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions tsc/internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -21442,6 +21442,25 @@ func (c *Checker) isReadonlyArraySymbol(symbol *ast.Symbol) bool {
// parameters and may differ in return types. When signatures differ in return types, the resulting return
// type is the union of the constituent return types.
func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature {
if core.Some(signatureLists, func(signatures []*Signature) bool { return len(signatures) > 1 }) {
signatureLists = core.Map(signatureLists, func(signatures []*Signature) []*Signature {
return core.FlatMap(signatures, func(signature *Signature) []*Signature {
minArgumentCount := c.getMinArgumentCount(signature)
parameterCount := c.getParameterCount(signature)
if len(signature.typeParameters) != 0 || c.hasEffectiveRestParameter(signature) || minArgumentCount == parameterCount {
return []*Signature{signature}
}
result := make([]*Signature, 0, parameterCount-minArgumentCount+1)
for arity := minArgumentCount; arity < parameterCount; arity++ {
variant := c.cloneSignature(signature)
variant.parameters = variant.parameters[:arity]
variant.minArgumentCount = int32(arity)
result = append(result, variant)
}
return append(result, signature)
})
})
}
var result []*Signature
var indexWithLengthOverOne int
var countLengthOverOne int
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
unionOverloadSignatureOrder.ts(55,19): error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type '"other"' is not assignable to parameter of type '"num" | "str"'.


==== unionOverloadSignatureOrder.ts (1 errors) ====
namespace Unprimed {
interface Alpha {
foo(n: "str", opt?: boolean): string;
}

interface Beta {
foo(n: "str", opt?: true): string;
foo(n: string): number | string;
}

declare let alphaBeta: Alpha | Beta;
declare let betaAlpha: Beta | Alpha;

const alphaBetaResult: string = alphaBeta.foo("str");
const betaAlphaResult: string = betaAlpha.foo("str");
}

namespace Primed {
interface Alpha {
foo(n: "str", opt?: boolean): string;
}

type B = Beta["foo"];

interface Beta {
foo(n: "str", opt?: true): string;
foo(n: string): number | string;
}

declare let alphaBeta: Alpha | Beta;
declare let betaAlpha: Beta | Alpha;

const alphaBetaResult: string = alphaBeta.foo("str");
const betaAlphaResult: string = betaAlpha.foo("str");
}

namespace MultipleOverloads {
interface Alpha {
foo(type: "num", opts?: unknown): number;
foo(type: "str", opts?: unknown): string;
foo(type: string, opts?: unknown): number | string;
}

interface Beta {
foo(type: "num", opts?: { a?: string }): number;
foo(type: "str", opts?: { b?: string }): string;
foo(type: "num" | "str", opts?: unknown): number | string;
}

declare let beta: Beta;
beta.foo("str");

declare let alphaBeta: Alpha | Beta;
const result: string = alphaBeta.foo("str");
alphaBeta.foo("other");
~~~~~~~
!!! error TS2769: No overload matches this call.
!!! error TS2769: The last overload gave the following error.
!!! error TS2769: Argument of type '"other"' is not assignable to parameter of type '"num" | "str"'.
!!! related TS2771 unionOverloadSignatureOrder.ts:47:9: The last overload is declared here.
alphaBeta.foo("str", false);
}

namespace ReversedDeclarations {
interface Beta {
foo(n: "str", opt?: true): string;
foo(n: string): number | string;
}

interface Alpha {
foo(n: "str", opt?: boolean): string;
}

declare let alphaBeta: Alpha | Beta;
const result: string = alphaBeta.foo("str");
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//// [tests/cases/compiler/unionOverloadSignatureOrder.ts] ////

//// [unionOverloadSignatureOrder.ts]
namespace Unprimed {
interface Alpha {
foo(n: "str", opt?: boolean): string;
}

interface Beta {
foo(n: "str", opt?: true): string;
foo(n: string): number | string;
}

declare let alphaBeta: Alpha | Beta;
declare let betaAlpha: Beta | Alpha;

const alphaBetaResult: string = alphaBeta.foo("str");
const betaAlphaResult: string = betaAlpha.foo("str");
}

namespace Primed {
interface Alpha {
foo(n: "str", opt?: boolean): string;
}

type B = Beta["foo"];

interface Beta {
foo(n: "str", opt?: true): string;
foo(n: string): number | string;
}

declare let alphaBeta: Alpha | Beta;
declare let betaAlpha: Beta | Alpha;

const alphaBetaResult: string = alphaBeta.foo("str");
const betaAlphaResult: string = betaAlpha.foo("str");
}

namespace MultipleOverloads {
interface Alpha {
foo(type: "num", opts?: unknown): number;
foo(type: "str", opts?: unknown): string;
foo(type: string, opts?: unknown): number | string;
}

interface Beta {
foo(type: "num", opts?: { a?: string }): number;
foo(type: "str", opts?: { b?: string }): string;
foo(type: "num" | "str", opts?: unknown): number | string;
}

declare let beta: Beta;
beta.foo("str");

declare let alphaBeta: Alpha | Beta;
const result: string = alphaBeta.foo("str");
alphaBeta.foo("other");
alphaBeta.foo("str", false);
}

namespace ReversedDeclarations {
interface Beta {
foo(n: "str", opt?: true): string;
foo(n: string): number | string;
}

interface Alpha {
foo(n: "str", opt?: boolean): string;
}

declare let alphaBeta: Alpha | Beta;
const result: string = alphaBeta.foo("str");
}


//// [unionOverloadSignatureOrder.js]
"use strict";
var Unprimed;
(function (Unprimed) {
const alphaBetaResult = alphaBeta.foo("str");
const betaAlphaResult = betaAlpha.foo("str");
})(Unprimed || (Unprimed = {}));
var Primed;
(function (Primed) {
const alphaBetaResult = alphaBeta.foo("str");
const betaAlphaResult = betaAlpha.foo("str");
})(Primed || (Primed = {}));
var MultipleOverloads;
(function (MultipleOverloads) {
beta.foo("str");
const result = alphaBeta.foo("str");
alphaBeta.foo("other");
alphaBeta.foo("str", false);
})(MultipleOverloads || (MultipleOverloads = {}));
var ReversedDeclarations;
(function (ReversedDeclarations) {
const result = alphaBeta.foo("str");
})(ReversedDeclarations || (ReversedDeclarations = {}));
Loading