diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 845f62365bb84..9722f552e51fa 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -21449,6 +21449,10 @@ func (c *Checker) isReadonlyArraySymbol(symbol *ast.Symbol) bool { // type is the union of the constituent return types. func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature { var result []*Signature + var priorities [][]int + orderedSignatureLists := core.Map(signatureLists, func(signatures []*Signature) []*Signature { + return c.reorderCandidates(signatures, SignatureFlagsNone) + }) var indexWithLengthOverOne int var countLengthOverOne int for i := range signatureLists { @@ -21483,7 +21487,28 @@ func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature s = c.createUnionSignature(signature, unionSignatures) s.thisParameter = thisParameter } - result = append(result, s) + priority := core.Map(orderedSignatureLists, func(signatures []*Signature) int { + return core.FindIndex(signatures, func(signature *Signature) bool { + return slices.Contains(unionSignatures, signature) + }) + }) + // A union candidate has precedence when its matching overloads occur no + // later in any constituent and earlier in at least one. + index := core.FindIndex(priorities, func(previous []int) bool { + earlier := false + for i, position := range priority { + if position < 0 || previous[i] < 0 || position > previous[i] { + return false + } + earlier = earlier || position < previous[i] + } + return earlier + }) + if index < 0 { + index = len(result) + } + result = slices.Insert(result, index, s) + priorities = slices.Insert(priorities, index, priority) } } } diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.errors.txt b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.errors.txt new file mode 100644 index 0000000000000..29a0457f9ed5d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.errors.txt @@ -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"); + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.js b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.js new file mode 100644 index 0000000000000..007c5be42f05f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.js @@ -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 = {})); diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.symbols b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.symbols new file mode 100644 index 0000000000000..855d3c0ae34a1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.symbols @@ -0,0 +1,214 @@ +//// [tests/cases/compiler/unionOverloadSignatureOrder.ts] //// + +=== unionOverloadSignatureOrder.ts === +namespace Unprimed { +>Unprimed : Symbol(Unprimed, Decl(unionOverloadSignatureOrder.ts, 0, 0)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 0, 20)) + + foo(n: "str", opt?: boolean): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignatureOrder.ts, 1, 21)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 2, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignatureOrder.ts, 2, 21)) + } + + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 3, 5)) + + foo(n: "str", opt?: true): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 5, 20), Decl(unionOverloadSignatureOrder.ts, 6, 42)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 6, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignatureOrder.ts, 6, 21)) + + foo(n: string): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 5, 20), Decl(unionOverloadSignatureOrder.ts, 6, 42)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 7, 12)) + } + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 10, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 0, 20)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 3, 5)) + + declare let betaAlpha: Beta | Alpha; +>betaAlpha : Symbol(betaAlpha, Decl(unionOverloadSignatureOrder.ts, 11, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 3, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 0, 20)) + + const alphaBetaResult: string = alphaBeta.foo("str"); +>alphaBetaResult : Symbol(alphaBetaResult, Decl(unionOverloadSignatureOrder.ts, 13, 9)) +>alphaBeta.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 1, 21), Decl(unionOverloadSignatureOrder.ts, 5, 20), Decl(unionOverloadSignatureOrder.ts, 6, 42)) +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 10, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 1, 21), Decl(unionOverloadSignatureOrder.ts, 5, 20), Decl(unionOverloadSignatureOrder.ts, 6, 42)) + + const betaAlphaResult: string = betaAlpha.foo("str"); +>betaAlphaResult : Symbol(betaAlphaResult, Decl(unionOverloadSignatureOrder.ts, 14, 9)) +>betaAlpha.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 1, 21), Decl(unionOverloadSignatureOrder.ts, 5, 20), Decl(unionOverloadSignatureOrder.ts, 6, 42)) +>betaAlpha : Symbol(betaAlpha, Decl(unionOverloadSignatureOrder.ts, 11, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 1, 21), Decl(unionOverloadSignatureOrder.ts, 5, 20), Decl(unionOverloadSignatureOrder.ts, 6, 42)) +} + +namespace Primed { +>Primed : Symbol(Primed, Decl(unionOverloadSignatureOrder.ts, 15, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 17, 18)) + + foo(n: "str", opt?: boolean): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignatureOrder.ts, 18, 21)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 19, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignatureOrder.ts, 19, 21)) + } + + type B = Beta["foo"]; +>B : Symbol(B, Decl(unionOverloadSignatureOrder.ts, 20, 5)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 22, 25)) + + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 22, 25)) + + foo(n: "str", opt?: true): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 24, 20), Decl(unionOverloadSignatureOrder.ts, 25, 42)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 25, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignatureOrder.ts, 25, 21)) + + foo(n: string): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 24, 20), Decl(unionOverloadSignatureOrder.ts, 25, 42)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 26, 12)) + } + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 29, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 17, 18)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 22, 25)) + + declare let betaAlpha: Beta | Alpha; +>betaAlpha : Symbol(betaAlpha, Decl(unionOverloadSignatureOrder.ts, 30, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 22, 25)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 17, 18)) + + const alphaBetaResult: string = alphaBeta.foo("str"); +>alphaBetaResult : Symbol(alphaBetaResult, Decl(unionOverloadSignatureOrder.ts, 32, 9)) +>alphaBeta.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 18, 21), Decl(unionOverloadSignatureOrder.ts, 24, 20), Decl(unionOverloadSignatureOrder.ts, 25, 42)) +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 29, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 18, 21), Decl(unionOverloadSignatureOrder.ts, 24, 20), Decl(unionOverloadSignatureOrder.ts, 25, 42)) + + const betaAlphaResult: string = betaAlpha.foo("str"); +>betaAlphaResult : Symbol(betaAlphaResult, Decl(unionOverloadSignatureOrder.ts, 33, 9)) +>betaAlpha.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 18, 21), Decl(unionOverloadSignatureOrder.ts, 24, 20), Decl(unionOverloadSignatureOrder.ts, 25, 42)) +>betaAlpha : Symbol(betaAlpha, Decl(unionOverloadSignatureOrder.ts, 30, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 18, 21), Decl(unionOverloadSignatureOrder.ts, 24, 20), Decl(unionOverloadSignatureOrder.ts, 25, 42)) +} + +namespace MultipleOverloads { +>MultipleOverloads : Symbol(MultipleOverloads, Decl(unionOverloadSignatureOrder.ts, 34, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 36, 29)) + + foo(type: "num", opts?: unknown): number; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49)) +>type : Symbol(type, Decl(unionOverloadSignatureOrder.ts, 38, 12)) +>opts : Symbol(opts, Decl(unionOverloadSignatureOrder.ts, 38, 24)) + + foo(type: "str", opts?: unknown): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49)) +>type : Symbol(type, Decl(unionOverloadSignatureOrder.ts, 39, 12)) +>opts : Symbol(opts, Decl(unionOverloadSignatureOrder.ts, 39, 24)) + + foo(type: string, opts?: unknown): number | string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49)) +>type : Symbol(type, Decl(unionOverloadSignatureOrder.ts, 40, 12)) +>opts : Symbol(opts, Decl(unionOverloadSignatureOrder.ts, 40, 25)) + } + + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 41, 5)) + + foo(type: "num", opts?: { a?: string }): number; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56), Decl(unionOverloadSignatureOrder.ts, 45, 56)) +>type : Symbol(type, Decl(unionOverloadSignatureOrder.ts, 44, 12)) +>opts : Symbol(opts, Decl(unionOverloadSignatureOrder.ts, 44, 24)) +>a : Symbol(a, Decl(unionOverloadSignatureOrder.ts, 44, 33)) + + foo(type: "str", opts?: { b?: string }): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56), Decl(unionOverloadSignatureOrder.ts, 45, 56)) +>type : Symbol(type, Decl(unionOverloadSignatureOrder.ts, 45, 12)) +>opts : Symbol(opts, Decl(unionOverloadSignatureOrder.ts, 45, 24)) +>b : Symbol(b, Decl(unionOverloadSignatureOrder.ts, 45, 33)) + + foo(type: "num" | "str", opts?: unknown): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56), Decl(unionOverloadSignatureOrder.ts, 45, 56)) +>type : Symbol(type, Decl(unionOverloadSignatureOrder.ts, 46, 12)) +>opts : Symbol(opts, Decl(unionOverloadSignatureOrder.ts, 46, 32)) + } + + declare let beta: Beta; +>beta : Symbol(beta, Decl(unionOverloadSignatureOrder.ts, 49, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 41, 5)) + + beta.foo("str"); +>beta.foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56), Decl(unionOverloadSignatureOrder.ts, 45, 56)) +>beta : Symbol(beta, Decl(unionOverloadSignatureOrder.ts, 49, 15)) +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56), Decl(unionOverloadSignatureOrder.ts, 45, 56)) + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 52, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 36, 29)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 41, 5)) + + const result: string = alphaBeta.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignatureOrder.ts, 53, 9)) +>alphaBeta.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49), Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56) ... and 1 more) +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 52, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49), Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56) ... and 1 more) + + alphaBeta.foo("other"); +>alphaBeta.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49), Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56) ... and 1 more) +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 52, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49), Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56) ... and 1 more) + + alphaBeta.foo("str", false); +>alphaBeta.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49), Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56) ... and 1 more) +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 52, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 37, 21), Decl(unionOverloadSignatureOrder.ts, 38, 49), Decl(unionOverloadSignatureOrder.ts, 39, 49), Decl(unionOverloadSignatureOrder.ts, 43, 20), Decl(unionOverloadSignatureOrder.ts, 44, 56) ... and 1 more) +} + +namespace ReversedDeclarations { +>ReversedDeclarations : Symbol(ReversedDeclarations, Decl(unionOverloadSignatureOrder.ts, 56, 1)) + + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 58, 32)) + + foo(n: "str", opt?: true): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 59, 20), Decl(unionOverloadSignatureOrder.ts, 60, 42)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 60, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignatureOrder.ts, 60, 21)) + + foo(n: string): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignatureOrder.ts, 59, 20), Decl(unionOverloadSignatureOrder.ts, 60, 42)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 61, 12)) + } + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 62, 5)) + + foo(n: "str", opt?: boolean): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignatureOrder.ts, 64, 21)) +>n : Symbol(n, Decl(unionOverloadSignatureOrder.ts, 65, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignatureOrder.ts, 65, 21)) + } + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 68, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignatureOrder.ts, 62, 5)) +>Beta : Symbol(Beta, Decl(unionOverloadSignatureOrder.ts, 58, 32)) + + const result: string = alphaBeta.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignatureOrder.ts, 69, 9)) +>alphaBeta.foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 64, 21), Decl(unionOverloadSignatureOrder.ts, 59, 20), Decl(unionOverloadSignatureOrder.ts, 60, 42)) +>alphaBeta : Symbol(alphaBeta, Decl(unionOverloadSignatureOrder.ts, 68, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignatureOrder.ts, 64, 21), Decl(unionOverloadSignatureOrder.ts, 59, 20), Decl(unionOverloadSignatureOrder.ts, 60, 42)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.types b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.types new file mode 100644 index 0000000000000..516748e96471a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignatureOrder.types @@ -0,0 +1,206 @@ +//// [tests/cases/compiler/unionOverloadSignatureOrder.ts] //// + +=== unionOverloadSignatureOrder.ts === +namespace Unprimed { +>Unprimed : typeof Unprimed + + interface Alpha { + foo(n: "str", opt?: boolean): string; +>foo : (n: "str", opt?: boolean) => string +>n : "str" +>opt : boolean | undefined + } + + interface Beta { + foo(n: "str", opt?: true): string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : "str" +>opt : true | undefined +>true : true + + foo(n: string): number | string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : string + } + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Alpha | Beta + + declare let betaAlpha: Beta | Alpha; +>betaAlpha : Alpha | Beta + + const alphaBetaResult: string = alphaBeta.foo("str"); +>alphaBetaResult : string +>alphaBeta.foo("str") : string +>alphaBeta.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>alphaBeta : Alpha | Beta +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>"str" : "str" + + const betaAlphaResult: string = betaAlpha.foo("str"); +>betaAlphaResult : string +>betaAlpha.foo("str") : string +>betaAlpha.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>betaAlpha : Alpha | Beta +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>"str" : "str" +} + +namespace Primed { +>Primed : typeof Primed + + interface Alpha { + foo(n: "str", opt?: boolean): string; +>foo : (n: "str", opt?: boolean) => string +>n : "str" +>opt : boolean | undefined + } + + type B = Beta["foo"]; +>B : { (n: "str", opt?: true): string; (n: string): number | string; } + + interface Beta { + foo(n: "str", opt?: true): string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : "str" +>opt : true | undefined +>true : true + + foo(n: string): number | string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : string + } + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Alpha | Beta + + declare let betaAlpha: Beta | Alpha; +>betaAlpha : Alpha | Beta + + const alphaBetaResult: string = alphaBeta.foo("str"); +>alphaBetaResult : string +>alphaBeta.foo("str") : string +>alphaBeta.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>alphaBeta : Alpha | Beta +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>"str" : "str" + + const betaAlphaResult: string = betaAlpha.foo("str"); +>betaAlphaResult : string +>betaAlpha.foo("str") : string +>betaAlpha.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>betaAlpha : Alpha | Beta +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } +>"str" : "str" +} + +namespace MultipleOverloads { +>MultipleOverloads : typeof MultipleOverloads + + interface Alpha { + foo(type: "num", opts?: unknown): number; +>foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } +>type : "num" +>opts : unknown + + foo(type: "str", opts?: unknown): string; +>foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } +>type : "str" +>opts : unknown + + foo(type: string, opts?: unknown): number | string; +>foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } +>type : string +>opts : unknown + } + + interface Beta { + foo(type: "num", opts?: { a?: string }): number; +>foo : { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>type : "num" +>opts : { a?: string; } | undefined +>a : string | undefined + + foo(type: "str", opts?: { b?: string }): string; +>foo : { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>type : "str" +>opts : { b?: string; } | undefined +>b : string | undefined + + foo(type: "num" | "str", opts?: unknown): number | string; +>foo : { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>type : "num" | "str" +>opts : unknown + } + + declare let beta: Beta; +>beta : Beta + + beta.foo("str"); +>beta.foo("str") : string +>beta.foo : { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>beta : Beta +>foo : { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>"str" : "str" + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Alpha | Beta + + const result: string = alphaBeta.foo("str"); +>result : string +>alphaBeta.foo("str") : string +>alphaBeta.foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } | { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>alphaBeta : Alpha | Beta +>foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } | { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>"str" : "str" + + alphaBeta.foo("other"); +>alphaBeta.foo("other") : never +>alphaBeta.foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } | { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>alphaBeta : Alpha | Beta +>foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } | { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>"other" : "other" + + alphaBeta.foo("str", false); +>alphaBeta.foo("str", false) : string | number +>alphaBeta.foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } | { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>alphaBeta : Alpha | Beta +>foo : { (type: "num", opts?: unknown): number; (type: "str", opts?: unknown): string; (type: string, opts?: unknown): number | string; } | { (type: "num", opts?: { a?: string; }): number; (type: "str", opts?: { b?: string; }): string; (type: "num" | "str", opts?: unknown): number | string; } +>"str" : "str" +>false : false +} + +namespace ReversedDeclarations { +>ReversedDeclarations : typeof ReversedDeclarations + + interface Beta { + foo(n: "str", opt?: true): string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : "str" +>opt : true | undefined +>true : true + + foo(n: string): number | string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : string + } + + interface Alpha { + foo(n: "str", opt?: boolean): string; +>foo : (n: "str", opt?: boolean) => string +>n : "str" +>opt : boolean | undefined + } + + declare let alphaBeta: Alpha | Beta; +>alphaBeta : Alpha | Beta + + const result: string = alphaBeta.foo("str"); +>result : string +>alphaBeta.foo("str") : string +>alphaBeta.foo : { (n: "str", opt?: true): string; (n: string): number | string; } | ((n: "str", opt?: boolean) => string) +>alphaBeta : Alpha | Beta +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } | ((n: "str", opt?: boolean) => string) +>"str" : "str" +} + diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.js b/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.js new file mode 100644 index 0000000000000..58d112070ada4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.js @@ -0,0 +1,246 @@ +//// [tests/cases/compiler/unionOverloadSignaturePriority.ts] //// + +//// [unionOverloadSignaturePriority.ts] +namespace TupleRest { + interface Alpha { + foo(...args: [n: "str", opt?: boolean]): string; + } + interface Beta { + foo(...args: [n: "str", opt?: true]): string; + foo(n: string): number | string; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result: string = value.foo("str"); + const reversedResult: string = reversed.foo("str"); + const withOption: string = value.foo("str", true); + // @ts-expect-error + value.foo(0); +} + +namespace RequiredTupleRest { + interface Alpha { + foo(...args: [n: "str", count: number, opt?: boolean]): string; + } + interface Beta { + foo(...args: [n: "str", count: number, opt?: true]): string; + foo(n: string, count: number): number | string; + } + declare let value: Alpha | Beta; + const result: string = value.foo("str", 1); + // @ts-expect-error + value.foo("str"); +} + +namespace OverlappingOverloads { + interface Alpha { + foo(n: "num", opt?: unknown): number; + foo(n: "str", opt?: unknown): string; + foo(n: string, opt?: unknown): number | string; + } + interface Beta { + foo(n: "num", opt?: { a?: string }): number; + foo(n: "str", opt?: { b?: string }): string; + foo(n: "num" | "str", opt?: unknown): number | string; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const str: string = value.foo("str"); + const num: number = value.foo("num"); + const reversedStr: string = reversed.foo("str"); + const reversedNum: number = reversed.foo("num"); + const fallback: number | string = value.foo("str", false); + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); + // @ts-expect-error + value.foo("other"); +} + +namespace RestArguments { + interface Alpha { + foo(n: "str", ...values: boolean[]): string; + } + interface Beta { + foo(n: "str", ...values: true[]): string; + foo(n: string, ...values: boolean[]): number | string; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result: string = value.foo("str"); + const withValues: string = value.foo("str", true, true); + const reversedResult: string = reversed.foo("str"); + const fallback: number | string = value.foo("str", false); + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); + // @ts-expect-error + value.foo("str", 1); +} + +namespace IncomparableOverloadPriorities { + interface Alpha { + foo(n: string, opt?: boolean): string; + foo(n: string | number): number; + } + interface Beta { + foo(n: string | number): boolean; + foo(n: string, opt?: true): Date; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result = value.foo("str"); + const reversedResult = reversed.foo("str"); + const consistent: typeof result = reversedResult; +} + +namespace IdenticalGenericSignatures { + interface Alpha { + foo(value: T, opt?: boolean): T; + } + interface Beta { + foo(value: T, opt?: boolean): T; + foo(n: string): number; + } + declare let value: Alpha | Beta; + const result: "str" = value.foo("str"); + const explicit: number = value.foo(1); + // @ts-expect-error + value.foo("str"); +} + +namespace ThreeConstituents { + interface Alpha { + foo(n: "str", opt?: boolean): string; + } + interface Beta { + foo(n: "str", opt?: true): string; + foo(n: string): number | string; + } + interface Gamma { + foo(n: "str", opt?: true): string; + foo(n: string): boolean | string; + } + declare let abc: Alpha | Beta | Gamma; + declare let acb: Alpha | Gamma | Beta; + declare let bac: Beta | Alpha | Gamma; + declare let bca: Beta | Gamma | Alpha; + declare let cab: Gamma | Alpha | Beta; + declare let cba: Gamma | Beta | Alpha; + const abcResult: string = abc.foo("str"); + const acbResult: string = acb.foo("str"); + const bacResult: string = bac.foo("str"); + const bcaResult: string = bca.foo("str"); + const cabResult: string = cab.foo("str"); + const cbaResult: string = cba.foo("str"); +} + +namespace ConstructSignatures { + interface Alpha { + new(n: "str", opt?: boolean): { value: string }; + } + interface Beta { + new(n: "str", opt?: true): { value: string }; + new(n: string): { value: number | string }; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result: string = new value("str").value; + const reversedResult: string = new reversed("str").value; + // @ts-expect-error + new value(1); +} + +namespace MergedDeclarations { + interface Alpha { + foo(n: string, opt?: unknown): string; + } + interface Beta { + foo(n: string, opt?: { a?: string }): string; + } + interface Beta { + foo(n: string): number; + } + declare let beta: Beta; + declare let value: Alpha | Beta; + const direct: number = beta.foo("str"); + const result: string | number = value.foo("str"); + // @ts-expect-error + const unsafeNarrow: string = value.foo("str"); +} + + + +//// [unionOverloadSignaturePriority.js] +"use strict"; +var TupleRest; +(function (TupleRest) { + const result = value.foo("str"); + const reversedResult = reversed.foo("str"); + const withOption = value.foo("str", true); + // @ts-expect-error + value.foo(0); +})(TupleRest || (TupleRest = {})); +var RequiredTupleRest; +(function (RequiredTupleRest) { + const result = value.foo("str", 1); + // @ts-expect-error + value.foo("str"); +})(RequiredTupleRest || (RequiredTupleRest = {})); +var OverlappingOverloads; +(function (OverlappingOverloads) { + const str = value.foo("str"); + const num = value.foo("num"); + const reversedStr = reversed.foo("str"); + const reversedNum = reversed.foo("num"); + const fallback = value.foo("str", false); + // @ts-expect-error + const narrowFallback = value.foo("str", false); + // @ts-expect-error + value.foo("other"); +})(OverlappingOverloads || (OverlappingOverloads = {})); +var RestArguments; +(function (RestArguments) { + const result = value.foo("str"); + const withValues = value.foo("str", true, true); + const reversedResult = reversed.foo("str"); + const fallback = value.foo("str", false); + // @ts-expect-error + const narrowFallback = value.foo("str", false); + // @ts-expect-error + value.foo("str", 1); +})(RestArguments || (RestArguments = {})); +var IncomparableOverloadPriorities; +(function (IncomparableOverloadPriorities) { + const result = value.foo("str"); + const reversedResult = reversed.foo("str"); + const consistent = reversedResult; +})(IncomparableOverloadPriorities || (IncomparableOverloadPriorities = {})); +var IdenticalGenericSignatures; +(function (IdenticalGenericSignatures) { + const result = value.foo("str"); + const explicit = value.foo(1); + // @ts-expect-error + value.foo("str"); +})(IdenticalGenericSignatures || (IdenticalGenericSignatures = {})); +var ThreeConstituents; +(function (ThreeConstituents) { + const abcResult = abc.foo("str"); + const acbResult = acb.foo("str"); + const bacResult = bac.foo("str"); + const bcaResult = bca.foo("str"); + const cabResult = cab.foo("str"); + const cbaResult = cba.foo("str"); +})(ThreeConstituents || (ThreeConstituents = {})); +var ConstructSignatures; +(function (ConstructSignatures) { + const result = new value("str").value; + const reversedResult = new reversed("str").value; + // @ts-expect-error + new value(1); +})(ConstructSignatures || (ConstructSignatures = {})); +var MergedDeclarations; +(function (MergedDeclarations) { + const direct = beta.foo("str"); + const result = value.foo("str"); + // @ts-expect-error + const unsafeNarrow = value.foo("str"); +})(MergedDeclarations || (MergedDeclarations = {})); diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.symbols b/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.symbols new file mode 100644 index 0000000000000..e0f3161a4c04c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.symbols @@ -0,0 +1,590 @@ +//// [tests/cases/compiler/unionOverloadSignaturePriority.ts] //// + +=== unionOverloadSignaturePriority.ts === +namespace TupleRest { +>TupleRest : Symbol(TupleRest, Decl(unionOverloadSignaturePriority.ts, 0, 0)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 0, 21)) + + foo(...args: [n: "str", opt?: boolean]): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 1, 21)) +>args : Symbol(args, Decl(unionOverloadSignaturePriority.ts, 2, 12)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 3, 5)) + + foo(...args: [n: "str", opt?: true]): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +>args : Symbol(args, Decl(unionOverloadSignaturePriority.ts, 5, 12)) + + foo(n: string): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 6, 12)) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 8, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 0, 21)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 3, 5)) + + declare let reversed: Beta | Alpha; +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 9, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 3, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 0, 21)) + + const result: string = value.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 10, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 8, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) + + const reversedResult: string = reversed.foo("str"); +>reversedResult : Symbol(reversedResult, Decl(unionOverloadSignaturePriority.ts, 11, 9)) +>reversed.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 9, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) + + const withOption: string = value.foo("str", true); +>withOption : Symbol(withOption, Decl(unionOverloadSignaturePriority.ts, 12, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 8, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) + + // @ts-expect-error + value.foo(0); +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 8, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 1, 21), Decl(unionOverloadSignaturePriority.ts, 4, 20), Decl(unionOverloadSignaturePriority.ts, 5, 53)) +} + +namespace RequiredTupleRest { +>RequiredTupleRest : Symbol(RequiredTupleRest, Decl(unionOverloadSignaturePriority.ts, 15, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 17, 29)) + + foo(...args: [n: "str", count: number, opt?: boolean]): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 18, 21)) +>args : Symbol(args, Decl(unionOverloadSignaturePriority.ts, 19, 12)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 20, 5)) + + foo(...args: [n: "str", count: number, opt?: true]): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 21, 20), Decl(unionOverloadSignaturePriority.ts, 22, 68)) +>args : Symbol(args, Decl(unionOverloadSignaturePriority.ts, 22, 12)) + + foo(n: string, count: number): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 21, 20), Decl(unionOverloadSignaturePriority.ts, 22, 68)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 23, 12)) +>count : Symbol(count, Decl(unionOverloadSignaturePriority.ts, 23, 22)) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 25, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 17, 29)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 20, 5)) + + const result: string = value.foo("str", 1); +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 26, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 18, 21), Decl(unionOverloadSignaturePriority.ts, 21, 20), Decl(unionOverloadSignaturePriority.ts, 22, 68)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 25, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 18, 21), Decl(unionOverloadSignaturePriority.ts, 21, 20), Decl(unionOverloadSignaturePriority.ts, 22, 68)) + + // @ts-expect-error + value.foo("str"); +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 18, 21), Decl(unionOverloadSignaturePriority.ts, 21, 20), Decl(unionOverloadSignaturePriority.ts, 22, 68)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 25, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 18, 21), Decl(unionOverloadSignaturePriority.ts, 21, 20), Decl(unionOverloadSignaturePriority.ts, 22, 68)) +} + +namespace OverlappingOverloads { +>OverlappingOverloads : Symbol(OverlappingOverloads, Decl(unionOverloadSignaturePriority.ts, 29, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 31, 32)) + + foo(n: "num", opt?: unknown): number; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 33, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 33, 21)) + + foo(n: "str", opt?: unknown): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 34, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 34, 21)) + + foo(n: string, opt?: unknown): number | string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 35, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 35, 22)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 36, 5)) + + foo(n: "num", opt?: { a?: string }): number; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52), Decl(unionOverloadSignaturePriority.ts, 39, 52)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 38, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 38, 21)) +>a : Symbol(a, Decl(unionOverloadSignaturePriority.ts, 38, 29)) + + foo(n: "str", opt?: { b?: string }): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52), Decl(unionOverloadSignaturePriority.ts, 39, 52)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 39, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 39, 21)) +>b : Symbol(b, Decl(unionOverloadSignaturePriority.ts, 39, 29)) + + foo(n: "num" | "str", opt?: unknown): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52), Decl(unionOverloadSignaturePriority.ts, 39, 52)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 40, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 40, 29)) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 42, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 31, 32)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 36, 5)) + + declare let reversed: Beta | Alpha; +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 43, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 36, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 31, 32)) + + const str: string = value.foo("str"); +>str : Symbol(str, Decl(unionOverloadSignaturePriority.ts, 44, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 42, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) + + const num: number = value.foo("num"); +>num : Symbol(num, Decl(unionOverloadSignaturePriority.ts, 45, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 42, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) + + const reversedStr: string = reversed.foo("str"); +>reversedStr : Symbol(reversedStr, Decl(unionOverloadSignaturePriority.ts, 46, 9)) +>reversed.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 43, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) + + const reversedNum: number = reversed.foo("num"); +>reversedNum : Symbol(reversedNum, Decl(unionOverloadSignaturePriority.ts, 47, 9)) +>reversed.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 43, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) + + const fallback: number | string = value.foo("str", false); +>fallback : Symbol(fallback, Decl(unionOverloadSignaturePriority.ts, 48, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 42, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) + + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); +>narrowFallback : Symbol(narrowFallback, Decl(unionOverloadSignaturePriority.ts, 50, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 42, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) + + // @ts-expect-error + value.foo("other"); +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 42, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 32, 21), Decl(unionOverloadSignaturePriority.ts, 33, 45), Decl(unionOverloadSignaturePriority.ts, 34, 45), Decl(unionOverloadSignaturePriority.ts, 37, 20), Decl(unionOverloadSignaturePriority.ts, 38, 52) ... and 1 more) +} + +namespace RestArguments { +>RestArguments : Symbol(RestArguments, Decl(unionOverloadSignaturePriority.ts, 53, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 55, 25)) + + foo(n: "str", ...values: boolean[]): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 56, 21)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 57, 12)) +>values : Symbol(values, Decl(unionOverloadSignaturePriority.ts, 57, 21)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 58, 5)) + + foo(n: "str", ...values: true[]): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 60, 12)) +>values : Symbol(values, Decl(unionOverloadSignaturePriority.ts, 60, 21)) + + foo(n: string, ...values: boolean[]): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 61, 12)) +>values : Symbol(values, Decl(unionOverloadSignaturePriority.ts, 61, 22)) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 63, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 55, 25)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 58, 5)) + + declare let reversed: Beta | Alpha; +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 64, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 58, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 55, 25)) + + const result: string = value.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 65, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 63, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) + + const withValues: string = value.foo("str", true, true); +>withValues : Symbol(withValues, Decl(unionOverloadSignaturePriority.ts, 66, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 63, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) + + const reversedResult: string = reversed.foo("str"); +>reversedResult : Symbol(reversedResult, Decl(unionOverloadSignaturePriority.ts, 67, 9)) +>reversed.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 64, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) + + const fallback: number | string = value.foo("str", false); +>fallback : Symbol(fallback, Decl(unionOverloadSignaturePriority.ts, 68, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 63, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) + + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); +>narrowFallback : Symbol(narrowFallback, Decl(unionOverloadSignaturePriority.ts, 70, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 63, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) + + // @ts-expect-error + value.foo("str", 1); +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 63, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 56, 21), Decl(unionOverloadSignaturePriority.ts, 59, 20), Decl(unionOverloadSignaturePriority.ts, 60, 49)) +} + +namespace IncomparableOverloadPriorities { +>IncomparableOverloadPriorities : Symbol(IncomparableOverloadPriorities, Decl(unionOverloadSignaturePriority.ts, 73, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 75, 42)) + + foo(n: string, opt?: boolean): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 76, 21), Decl(unionOverloadSignaturePriority.ts, 77, 46)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 77, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 77, 22)) + + foo(n: string | number): number; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 76, 21), Decl(unionOverloadSignaturePriority.ts, 77, 46)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 78, 12)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 79, 5)) + + foo(n: string | number): boolean; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 80, 20), Decl(unionOverloadSignaturePriority.ts, 81, 41)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 81, 12)) + + foo(n: string, opt?: true): Date; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 80, 20), Decl(unionOverloadSignaturePriority.ts, 81, 41)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 82, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 82, 22)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 1 more) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 84, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 75, 42)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 79, 5)) + + declare let reversed: Beta | Alpha; +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 85, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 79, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 75, 42)) + + const result = value.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 86, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 76, 21), Decl(unionOverloadSignaturePriority.ts, 77, 46), Decl(unionOverloadSignaturePriority.ts, 80, 20), Decl(unionOverloadSignaturePriority.ts, 81, 41)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 84, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 76, 21), Decl(unionOverloadSignaturePriority.ts, 77, 46), Decl(unionOverloadSignaturePriority.ts, 80, 20), Decl(unionOverloadSignaturePriority.ts, 81, 41)) + + const reversedResult = reversed.foo("str"); +>reversedResult : Symbol(reversedResult, Decl(unionOverloadSignaturePriority.ts, 87, 9)) +>reversed.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 76, 21), Decl(unionOverloadSignaturePriority.ts, 77, 46), Decl(unionOverloadSignaturePriority.ts, 80, 20), Decl(unionOverloadSignaturePriority.ts, 81, 41)) +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 85, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 76, 21), Decl(unionOverloadSignaturePriority.ts, 77, 46), Decl(unionOverloadSignaturePriority.ts, 80, 20), Decl(unionOverloadSignaturePriority.ts, 81, 41)) + + const consistent: typeof result = reversedResult; +>consistent : Symbol(consistent, Decl(unionOverloadSignaturePriority.ts, 88, 9)) +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 86, 9)) +>reversedResult : Symbol(reversedResult, Decl(unionOverloadSignaturePriority.ts, 87, 9)) +} + +namespace IdenticalGenericSignatures { +>IdenticalGenericSignatures : Symbol(IdenticalGenericSignatures, Decl(unionOverloadSignaturePriority.ts, 89, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 91, 38)) + + foo(value: T, opt?: boolean): T; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 92, 21)) +>T : Symbol(T, Decl(unionOverloadSignaturePriority.ts, 93, 12)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 93, 15)) +>T : Symbol(T, Decl(unionOverloadSignaturePriority.ts, 93, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 93, 24)) +>T : Symbol(T, Decl(unionOverloadSignaturePriority.ts, 93, 12)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 94, 5)) + + foo(value: T, opt?: boolean): T; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) +>T : Symbol(T, Decl(unionOverloadSignaturePriority.ts, 96, 12)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 96, 15)) +>T : Symbol(T, Decl(unionOverloadSignaturePriority.ts, 96, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 96, 24)) +>T : Symbol(T, Decl(unionOverloadSignaturePriority.ts, 96, 12)) + + foo(n: string): number; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 97, 12)) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 99, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 91, 38)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 94, 5)) + + const result: "str" = value.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 100, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 92, 21), Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 99, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 92, 21), Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) + + const explicit: number = value.foo(1); +>explicit : Symbol(explicit, Decl(unionOverloadSignaturePriority.ts, 101, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 92, 21), Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 99, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 92, 21), Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) + + // @ts-expect-error + value.foo("str"); +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 92, 21), Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 99, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 92, 21), Decl(unionOverloadSignaturePriority.ts, 95, 20), Decl(unionOverloadSignaturePriority.ts, 96, 43)) +} + +namespace ThreeConstituents { +>ThreeConstituents : Symbol(ThreeConstituents, Decl(unionOverloadSignaturePriority.ts, 104, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) + + foo(n: "str", opt?: boolean): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 107, 21)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 108, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 108, 21)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) + + foo(n: "str", opt?: true): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 111, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 111, 21)) + + foo(n: string): number | string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 112, 12)) + } + interface Gamma { +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) + + foo(n: "str", opt?: true): string; +>foo : Symbol(Gamma.foo, Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 115, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 115, 21)) + + foo(n: string): boolean | string; +>foo : Symbol(Gamma.foo, Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 116, 12)) + } + declare let abc: Alpha | Beta | Gamma; +>abc : Symbol(abc, Decl(unionOverloadSignaturePriority.ts, 118, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) + + declare let acb: Alpha | Gamma | Beta; +>acb : Symbol(acb, Decl(unionOverloadSignaturePriority.ts, 119, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) + + declare let bac: Beta | Alpha | Gamma; +>bac : Symbol(bac, Decl(unionOverloadSignaturePriority.ts, 120, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) + + declare let bca: Beta | Gamma | Alpha; +>bca : Symbol(bca, Decl(unionOverloadSignaturePriority.ts, 121, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) + + declare let cab: Gamma | Alpha | Beta; +>cab : Symbol(cab, Decl(unionOverloadSignaturePriority.ts, 122, 15)) +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) + + declare let cba: Gamma | Beta | Alpha; +>cba : Symbol(cba, Decl(unionOverloadSignaturePriority.ts, 123, 15)) +>Gamma : Symbol(Gamma, Decl(unionOverloadSignaturePriority.ts, 113, 5)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 109, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 106, 29)) + + const abcResult: string = abc.foo("str"); +>abcResult : Symbol(abcResult, Decl(unionOverloadSignaturePriority.ts, 124, 9)) +>abc.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>abc : Symbol(abc, Decl(unionOverloadSignaturePriority.ts, 118, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) + + const acbResult: string = acb.foo("str"); +>acbResult : Symbol(acbResult, Decl(unionOverloadSignaturePriority.ts, 125, 9)) +>acb.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>acb : Symbol(acb, Decl(unionOverloadSignaturePriority.ts, 119, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) + + const bacResult: string = bac.foo("str"); +>bacResult : Symbol(bacResult, Decl(unionOverloadSignaturePriority.ts, 126, 9)) +>bac.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>bac : Symbol(bac, Decl(unionOverloadSignaturePriority.ts, 120, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) + + const bcaResult: string = bca.foo("str"); +>bcaResult : Symbol(bcaResult, Decl(unionOverloadSignaturePriority.ts, 127, 9)) +>bca.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>bca : Symbol(bca, Decl(unionOverloadSignaturePriority.ts, 121, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) + + const cabResult: string = cab.foo("str"); +>cabResult : Symbol(cabResult, Decl(unionOverloadSignaturePriority.ts, 128, 9)) +>cab.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>cab : Symbol(cab, Decl(unionOverloadSignaturePriority.ts, 122, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) + + const cbaResult: string = cba.foo("str"); +>cbaResult : Symbol(cbaResult, Decl(unionOverloadSignaturePriority.ts, 129, 9)) +>cba.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +>cba : Symbol(cba, Decl(unionOverloadSignaturePriority.ts, 123, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 107, 21), Decl(unionOverloadSignaturePriority.ts, 110, 20), Decl(unionOverloadSignaturePriority.ts, 111, 42), Decl(unionOverloadSignaturePriority.ts, 114, 21), Decl(unionOverloadSignaturePriority.ts, 115, 42)) +} + +namespace ConstructSignatures { +>ConstructSignatures : Symbol(ConstructSignatures, Decl(unionOverloadSignaturePriority.ts, 130, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 132, 31)) + + new(n: "str", opt?: boolean): { value: string }; +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 134, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 134, 21)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 134, 39)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 135, 5)) + + new(n: "str", opt?: true): { value: string }; +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 137, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 137, 21)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 137, 36)) + + new(n: string): { value: number | string }; +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 138, 12)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 138, 25)) + } + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 140, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 132, 31)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 135, 5)) + + declare let reversed: Beta | Alpha; +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 141, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 135, 5)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 132, 31)) + + const result: string = new value("str").value; +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 142, 9)) +>new value("str").value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 134, 39)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 140, 15)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 134, 39)) + + const reversedResult: string = new reversed("str").value; +>reversedResult : Symbol(reversedResult, Decl(unionOverloadSignaturePriority.ts, 143, 9)) +>new reversed("str").value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 134, 39)) +>reversed : Symbol(reversed, Decl(unionOverloadSignaturePriority.ts, 141, 15)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 134, 39)) + + // @ts-expect-error + new value(1); +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 140, 15)) +} + +namespace MergedDeclarations { +>MergedDeclarations : Symbol(MergedDeclarations, Decl(unionOverloadSignaturePriority.ts, 146, 1)) + + interface Alpha { +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 148, 30)) + + foo(n: string, opt?: unknown): string; +>foo : Symbol(Alpha.foo, Decl(unionOverloadSignaturePriority.ts, 149, 21)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 150, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 150, 22)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 151, 5), Decl(unionOverloadSignaturePriority.ts, 154, 5)) + + foo(n: string, opt?: { a?: string }): string; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 153, 12)) +>opt : Symbol(opt, Decl(unionOverloadSignaturePriority.ts, 153, 22)) +>a : Symbol(a, Decl(unionOverloadSignaturePriority.ts, 153, 30)) + } + interface Beta { +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 151, 5), Decl(unionOverloadSignaturePriority.ts, 154, 5)) + + foo(n: string): number; +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) +>n : Symbol(n, Decl(unionOverloadSignaturePriority.ts, 156, 12)) + } + declare let beta: Beta; +>beta : Symbol(beta, Decl(unionOverloadSignaturePriority.ts, 158, 15)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 151, 5), Decl(unionOverloadSignaturePriority.ts, 154, 5)) + + declare let value: Alpha | Beta; +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 159, 15)) +>Alpha : Symbol(Alpha, Decl(unionOverloadSignaturePriority.ts, 148, 30)) +>Beta : Symbol(Beta, Decl(unionOverloadSignaturePriority.ts, 151, 5), Decl(unionOverloadSignaturePriority.ts, 154, 5)) + + const direct: number = beta.foo("str"); +>direct : Symbol(direct, Decl(unionOverloadSignaturePriority.ts, 160, 9)) +>beta.foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) +>beta : Symbol(beta, Decl(unionOverloadSignaturePriority.ts, 158, 15)) +>foo : Symbol(Beta.foo, Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) + + const result: string | number = value.foo("str"); +>result : Symbol(result, Decl(unionOverloadSignaturePriority.ts, 161, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 149, 21), Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 159, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 149, 21), Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) + + // @ts-expect-error + const unsafeNarrow: string = value.foo("str"); +>unsafeNarrow : Symbol(unsafeNarrow, Decl(unionOverloadSignaturePriority.ts, 163, 9)) +>value.foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 149, 21), Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) +>value : Symbol(value, Decl(unionOverloadSignaturePriority.ts, 159, 15)) +>foo : Symbol(foo, Decl(unionOverloadSignaturePriority.ts, 149, 21), Decl(unionOverloadSignaturePriority.ts, 152, 20), Decl(unionOverloadSignaturePriority.ts, 155, 20)) +} + + diff --git a/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.types b/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.types new file mode 100644 index 0000000000000..da738d05908cf --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/unionOverloadSignaturePriority.types @@ -0,0 +1,586 @@ +//// [tests/cases/compiler/unionOverloadSignaturePriority.ts] //// + +=== unionOverloadSignaturePriority.ts === +namespace TupleRest { +>TupleRest : typeof TupleRest + + interface Alpha { + foo(...args: [n: "str", opt?: boolean]): string; +>foo : (n: "str", opt?: boolean | undefined) => string +>args : [n: "str", opt?: boolean | undefined] + } + interface Beta { + foo(...args: [n: "str", opt?: true]): string; +>foo : { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>args : [n: "str", opt?: true | undefined] +>true : true + + foo(n: string): number | string; +>foo : { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>n : string + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + declare let reversed: Beta | Alpha; +>reversed : Alpha | Beta + + const result: string = value.foo("str"); +>result : string +>value.foo("str") : string +>value.foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>"str" : "str" + + const reversedResult: string = reversed.foo("str"); +>reversedResult : string +>reversed.foo("str") : string +>reversed.foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>reversed : Alpha | Beta +>foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>"str" : "str" + + const withOption: string = value.foo("str", true); +>withOption : string +>value.foo("str", true) : string +>value.foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>"str" : "str" +>true : true + + // @ts-expect-error + value.foo(0); +>value.foo(0) : string +>value.foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", opt?: boolean | undefined) => string) | { (n: "str", opt?: true | undefined): string; (n: string): number | string; } +>0 : 0 +} + +namespace RequiredTupleRest { +>RequiredTupleRest : typeof RequiredTupleRest + + interface Alpha { + foo(...args: [n: "str", count: number, opt?: boolean]): string; +>foo : (n: "str", count: number, opt?: boolean | undefined) => string +>args : [n: "str", count: number, opt?: boolean | undefined] + } + interface Beta { + foo(...args: [n: "str", count: number, opt?: true]): string; +>foo : { (n: "str", count: number, opt?: true | undefined): string; (n: string, count: number): number | string; } +>args : [n: "str", count: number, opt?: true | undefined] +>true : true + + foo(n: string, count: number): number | string; +>foo : { (n: "str", count: number, opt?: true | undefined): string; (n: string, count: number): number | string; } +>n : string +>count : number + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + const result: string = value.foo("str", 1); +>result : string +>value.foo("str", 1) : string +>value.foo : ((n: "str", count: number, opt?: boolean | undefined) => string) | { (n: "str", count: number, opt?: true | undefined): string; (n: string, count: number): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", count: number, opt?: boolean | undefined) => string) | { (n: "str", count: number, opt?: true | undefined): string; (n: string, count: number): number | string; } +>"str" : "str" +>1 : 1 + + // @ts-expect-error + value.foo("str"); +>value.foo("str") : string +>value.foo : ((n: "str", count: number, opt?: boolean | undefined) => string) | { (n: "str", count: number, opt?: true | undefined): string; (n: string, count: number): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", count: number, opt?: boolean | undefined) => string) | { (n: "str", count: number, opt?: true | undefined): string; (n: string, count: number): number | string; } +>"str" : "str" +} + +namespace OverlappingOverloads { +>OverlappingOverloads : typeof OverlappingOverloads + + interface Alpha { + foo(n: "num", opt?: unknown): number; +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } +>n : "num" +>opt : unknown + + foo(n: "str", opt?: unknown): string; +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } +>n : "str" +>opt : unknown + + foo(n: string, opt?: unknown): number | string; +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } +>n : string +>opt : unknown + } + interface Beta { + foo(n: "num", opt?: { a?: string }): number; +>foo : { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>n : "num" +>opt : { a?: string; } | undefined +>a : string | undefined + + foo(n: "str", opt?: { b?: string }): string; +>foo : { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>n : "str" +>opt : { b?: string; } | undefined +>b : string | undefined + + foo(n: "num" | "str", opt?: unknown): number | string; +>foo : { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>n : "num" | "str" +>opt : unknown + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + declare let reversed: Beta | Alpha; +>reversed : Alpha | Beta + + const str: string = value.foo("str"); +>str : string +>value.foo("str") : string +>value.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>value : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"str" : "str" + + const num: number = value.foo("num"); +>num : number +>value.foo("num") : number +>value.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>value : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"num" : "num" + + const reversedStr: string = reversed.foo("str"); +>reversedStr : string +>reversed.foo("str") : string +>reversed.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>reversed : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"str" : "str" + + const reversedNum: number = reversed.foo("num"); +>reversedNum : number +>reversed.foo("num") : number +>reversed.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>reversed : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"num" : "num" + + const fallback: number | string = value.foo("str", false); +>fallback : string | number +>value.foo("str", false) : string | number +>value.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>value : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"str" : "str" +>false : false + + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); +>narrowFallback : string +>value.foo("str", false) : string | number +>value.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>value : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"str" : "str" +>false : false + + // @ts-expect-error + value.foo("other"); +>value.foo("other") : never +>value.foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>value : Alpha | Beta +>foo : { (n: "num", opt?: unknown): number; (n: "str", opt?: unknown): string; (n: string, opt?: unknown): number | string; } | { (n: "num", opt?: { a?: string; }): number; (n: "str", opt?: { b?: string; }): string; (n: "num" | "str", opt?: unknown): number | string; } +>"other" : "other" +} + +namespace RestArguments { +>RestArguments : typeof RestArguments + + interface Alpha { + foo(n: "str", ...values: boolean[]): string; +>foo : (n: "str", ...values: boolean[]) => string +>n : "str" +>values : boolean[] + } + interface Beta { + foo(n: "str", ...values: true[]): string; +>foo : { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>n : "str" +>values : true[] +>true : true + + foo(n: string, ...values: boolean[]): number | string; +>foo : { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>n : string +>values : boolean[] + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + declare let reversed: Beta | Alpha; +>reversed : Alpha | Beta + + const result: string = value.foo("str"); +>result : string +>value.foo("str") : string +>value.foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>"str" : "str" + + const withValues: string = value.foo("str", true, true); +>withValues : string +>value.foo("str", true, true) : string +>value.foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>"str" : "str" +>true : true +>true : true + + const reversedResult: string = reversed.foo("str"); +>reversedResult : string +>reversed.foo("str") : string +>reversed.foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>reversed : Alpha | Beta +>foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>"str" : "str" + + const fallback: number | string = value.foo("str", false); +>fallback : string | number +>value.foo("str", false) : string | number +>value.foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>"str" : "str" +>false : false + + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); +>narrowFallback : string +>value.foo("str", false) : string | number +>value.foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>"str" : "str" +>false : false + + // @ts-expect-error + value.foo("str", 1); +>value.foo("str", 1) : string +>value.foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>value : Alpha | Beta +>foo : ((n: "str", ...values: boolean[]) => string) | { (n: "str", ...values: true[]): string; (n: string, ...values: boolean[]): number | string; } +>"str" : "str" +>1 : 1 +} + +namespace IncomparableOverloadPriorities { +>IncomparableOverloadPriorities : typeof IncomparableOverloadPriorities + + interface Alpha { + foo(n: string, opt?: boolean): string; +>foo : { (n: string, opt?: boolean): string; (n: string | number): number; } +>n : string +>opt : boolean | undefined + + foo(n: string | number): number; +>foo : { (n: string, opt?: boolean): string; (n: string | number): number; } +>n : string | number + } + interface Beta { + foo(n: string | number): boolean; +>foo : { (n: string | number): boolean; (n: string, opt?: true): Date; } +>n : string | number + + foo(n: string, opt?: true): Date; +>foo : { (n: string | number): boolean; (n: string, opt?: true): Date; } +>n : string +>opt : true | undefined +>true : true + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + declare let reversed: Beta | Alpha; +>reversed : Alpha | Beta + + const result = value.foo("str"); +>result : string | Date +>value.foo("str") : string | Date +>value.foo : { (n: string, opt?: boolean): string; (n: string | number): number; } | { (n: string | number): boolean; (n: string, opt?: true): Date; } +>value : Alpha | Beta +>foo : { (n: string, opt?: boolean): string; (n: string | number): number; } | { (n: string | number): boolean; (n: string, opt?: true): Date; } +>"str" : "str" + + const reversedResult = reversed.foo("str"); +>reversedResult : string | Date +>reversed.foo("str") : string | Date +>reversed.foo : { (n: string, opt?: boolean): string; (n: string | number): number; } | { (n: string | number): boolean; (n: string, opt?: true): Date; } +>reversed : Alpha | Beta +>foo : { (n: string, opt?: boolean): string; (n: string | number): number; } | { (n: string | number): boolean; (n: string, opt?: true): Date; } +>"str" : "str" + + const consistent: typeof result = reversedResult; +>consistent : string | Date +>result : string | Date +>reversedResult : string | Date +} + +namespace IdenticalGenericSignatures { +>IdenticalGenericSignatures : typeof IdenticalGenericSignatures + + interface Alpha { + foo(value: T, opt?: boolean): T; +>foo : (value: T, opt?: boolean) => T +>value : T +>opt : boolean | undefined + } + interface Beta { + foo(value: T, opt?: boolean): T; +>foo : { (value: T, opt?: boolean): T; (n: string): number; } +>value : T +>opt : boolean | undefined + + foo(n: string): number; +>foo : { (value: T, opt?: boolean): T; (n: string): number; } +>n : string + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + const result: "str" = value.foo("str"); +>result : "str" +>value.foo("str") : "str" +>value.foo : ((value: T, opt?: boolean) => T) | { (value: T, opt?: boolean): T; (n: string): number; } +>value : Alpha | Beta +>foo : ((value: T, opt?: boolean) => T) | { (value: T, opt?: boolean): T; (n: string): number; } +>"str" : "str" + + const explicit: number = value.foo(1); +>explicit : number +>value.foo(1) : number +>value.foo : ((value: T, opt?: boolean) => T) | { (value: T, opt?: boolean): T; (n: string): number; } +>value : Alpha | Beta +>foo : ((value: T, opt?: boolean) => T) | { (value: T, opt?: boolean): T; (n: string): number; } +>1 : 1 + + // @ts-expect-error + value.foo("str"); +>value.foo("str") : number +>value.foo : ((value: T, opt?: boolean) => T) | { (value: T, opt?: boolean): T; (n: string): number; } +>value : Alpha | Beta +>foo : ((value: T, opt?: boolean) => T) | { (value: T, opt?: boolean): T; (n: string): number; } +>"str" : "str" +} + +namespace ThreeConstituents { +>ThreeConstituents : typeof ThreeConstituents + + interface Alpha { + foo(n: "str", opt?: boolean): string; +>foo : (n: "str", opt?: boolean) => string +>n : "str" +>opt : boolean | undefined + } + interface Beta { + foo(n: "str", opt?: true): string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : "str" +>opt : true | undefined +>true : true + + foo(n: string): number | string; +>foo : { (n: "str", opt?: true): string; (n: string): number | string; } +>n : string + } + interface Gamma { + foo(n: "str", opt?: true): string; +>foo : { (n: "str", opt?: true): string; (n: string): boolean | string; } +>n : "str" +>opt : true | undefined +>true : true + + foo(n: string): boolean | string; +>foo : { (n: "str", opt?: true): string; (n: string): boolean | string; } +>n : string + } + declare let abc: Alpha | Beta | Gamma; +>abc : Alpha | Beta | Gamma + + declare let acb: Alpha | Gamma | Beta; +>acb : Alpha | Beta | Gamma + + declare let bac: Beta | Alpha | Gamma; +>bac : Alpha | Beta | Gamma + + declare let bca: Beta | Gamma | Alpha; +>bca : Alpha | Beta | Gamma + + declare let cab: Gamma | Alpha | Beta; +>cab : Alpha | Beta | Gamma + + declare let cba: Gamma | Beta | Alpha; +>cba : Alpha | Beta | Gamma + + const abcResult: string = abc.foo("str"); +>abcResult : string +>abc.foo("str") : string +>abc.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>abc : Alpha | Beta | Gamma +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>"str" : "str" + + const acbResult: string = acb.foo("str"); +>acbResult : string +>acb.foo("str") : string +>acb.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>acb : Alpha | Beta | Gamma +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>"str" : "str" + + const bacResult: string = bac.foo("str"); +>bacResult : string +>bac.foo("str") : string +>bac.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>bac : Alpha | Beta | Gamma +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>"str" : "str" + + const bcaResult: string = bca.foo("str"); +>bcaResult : string +>bca.foo("str") : string +>bca.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>bca : Alpha | Beta | Gamma +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>"str" : "str" + + const cabResult: string = cab.foo("str"); +>cabResult : string +>cab.foo("str") : string +>cab.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>cab : Alpha | Beta | Gamma +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>"str" : "str" + + const cbaResult: string = cba.foo("str"); +>cbaResult : string +>cba.foo("str") : string +>cba.foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>cba : Alpha | Beta | Gamma +>foo : ((n: "str", opt?: boolean) => string) | { (n: "str", opt?: true): string; (n: string): number | string; } | { (n: "str", opt?: true): string; (n: string): boolean | string; } +>"str" : "str" +} + +namespace ConstructSignatures { +>ConstructSignatures : typeof ConstructSignatures + + interface Alpha { + new(n: "str", opt?: boolean): { value: string }; +>n : "str" +>opt : boolean | undefined +>value : string + } + interface Beta { + new(n: "str", opt?: true): { value: string }; +>n : "str" +>opt : true | undefined +>true : true +>value : string + + new(n: string): { value: number | string }; +>n : string +>value : string | number + } + declare let value: Alpha | Beta; +>value : Alpha | Beta + + declare let reversed: Beta | Alpha; +>reversed : Alpha | Beta + + const result: string = new value("str").value; +>result : string +>new value("str").value : string +>new value("str") : { value: string; } +>value : Alpha | Beta +>"str" : "str" +>value : string + + const reversedResult: string = new reversed("str").value; +>reversedResult : string +>new reversed("str").value : string +>new reversed("str") : { value: string; } +>reversed : Alpha | Beta +>"str" : "str" +>value : string + + // @ts-expect-error + new value(1); +>new value(1) : { value: string; } & { value: number | string; } +>value : Alpha | Beta +>1 : 1 +} + +namespace MergedDeclarations { +>MergedDeclarations : typeof MergedDeclarations + + interface Alpha { + foo(n: string, opt?: unknown): string; +>foo : (n: string, opt?: unknown) => string +>n : string +>opt : unknown + } + interface Beta { + foo(n: string, opt?: { a?: string }): string; +>foo : { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>n : string +>opt : { a?: string; } | undefined +>a : string | undefined + } + interface Beta { + foo(n: string): number; +>foo : { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>n : string + } + declare let beta: Beta; +>beta : Beta + + declare let value: Alpha | Beta; +>value : Alpha | Beta + + const direct: number = beta.foo("str"); +>direct : number +>beta.foo("str") : number +>beta.foo : { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>beta : Beta +>foo : { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>"str" : "str" + + const result: string | number = value.foo("str"); +>result : string | number +>value.foo("str") : string | number +>value.foo : ((n: string, opt?: unknown) => string) | { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>value : Alpha | Beta +>foo : ((n: string, opt?: unknown) => string) | { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>"str" : "str" + + // @ts-expect-error + const unsafeNarrow: string = value.foo("str"); +>unsafeNarrow : string +>value.foo("str") : string | number +>value.foo : ((n: string, opt?: unknown) => string) | { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>value : Alpha | Beta +>foo : ((n: string, opt?: unknown) => string) | { (n: string, opt?: { a?: string; }): string; (n: string): number; } +>"str" : "str" +} + + diff --git a/tsc/testdata/tests/cases/compiler/unionOverloadSignatureOrder.ts b/tsc/testdata/tests/cases/compiler/unionOverloadSignatureOrder.ts new file mode 100644 index 0000000000000..956605abb8b1e --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/unionOverloadSignatureOrder.ts @@ -0,0 +1,73 @@ +// @strict: true + +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"); +} diff --git a/tsc/testdata/tests/cases/compiler/unionOverloadSignaturePriority.ts b/tsc/testdata/tests/cases/compiler/unionOverloadSignaturePriority.ts new file mode 100644 index 0000000000000..57b07366beda5 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/unionOverloadSignaturePriority.ts @@ -0,0 +1,168 @@ +// @strict: true + +namespace TupleRest { + interface Alpha { + foo(...args: [n: "str", opt?: boolean]): string; + } + interface Beta { + foo(...args: [n: "str", opt?: true]): string; + foo(n: string): number | string; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result: string = value.foo("str"); + const reversedResult: string = reversed.foo("str"); + const withOption: string = value.foo("str", true); + // @ts-expect-error + value.foo(0); +} + +namespace RequiredTupleRest { + interface Alpha { + foo(...args: [n: "str", count: number, opt?: boolean]): string; + } + interface Beta { + foo(...args: [n: "str", count: number, opt?: true]): string; + foo(n: string, count: number): number | string; + } + declare let value: Alpha | Beta; + const result: string = value.foo("str", 1); + // @ts-expect-error + value.foo("str"); +} + +namespace OverlappingOverloads { + interface Alpha { + foo(n: "num", opt?: unknown): number; + foo(n: "str", opt?: unknown): string; + foo(n: string, opt?: unknown): number | string; + } + interface Beta { + foo(n: "num", opt?: { a?: string }): number; + foo(n: "str", opt?: { b?: string }): string; + foo(n: "num" | "str", opt?: unknown): number | string; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const str: string = value.foo("str"); + const num: number = value.foo("num"); + const reversedStr: string = reversed.foo("str"); + const reversedNum: number = reversed.foo("num"); + const fallback: number | string = value.foo("str", false); + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); + // @ts-expect-error + value.foo("other"); +} + +namespace RestArguments { + interface Alpha { + foo(n: "str", ...values: boolean[]): string; + } + interface Beta { + foo(n: "str", ...values: true[]): string; + foo(n: string, ...values: boolean[]): number | string; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result: string = value.foo("str"); + const withValues: string = value.foo("str", true, true); + const reversedResult: string = reversed.foo("str"); + const fallback: number | string = value.foo("str", false); + // @ts-expect-error + const narrowFallback: string = value.foo("str", false); + // @ts-expect-error + value.foo("str", 1); +} + +namespace IncomparableOverloadPriorities { + interface Alpha { + foo(n: string, opt?: boolean): string; + foo(n: string | number): number; + } + interface Beta { + foo(n: string | number): boolean; + foo(n: string, opt?: true): Date; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result = value.foo("str"); + const reversedResult = reversed.foo("str"); + const consistent: typeof result = reversedResult; +} + +namespace IdenticalGenericSignatures { + interface Alpha { + foo(value: T, opt?: boolean): T; + } + interface Beta { + foo(value: T, opt?: boolean): T; + foo(n: string): number; + } + declare let value: Alpha | Beta; + const result: "str" = value.foo("str"); + const explicit: number = value.foo(1); + // @ts-expect-error + value.foo("str"); +} + +namespace ThreeConstituents { + interface Alpha { + foo(n: "str", opt?: boolean): string; + } + interface Beta { + foo(n: "str", opt?: true): string; + foo(n: string): number | string; + } + interface Gamma { + foo(n: "str", opt?: true): string; + foo(n: string): boolean | string; + } + declare let abc: Alpha | Beta | Gamma; + declare let acb: Alpha | Gamma | Beta; + declare let bac: Beta | Alpha | Gamma; + declare let bca: Beta | Gamma | Alpha; + declare let cab: Gamma | Alpha | Beta; + declare let cba: Gamma | Beta | Alpha; + const abcResult: string = abc.foo("str"); + const acbResult: string = acb.foo("str"); + const bacResult: string = bac.foo("str"); + const bcaResult: string = bca.foo("str"); + const cabResult: string = cab.foo("str"); + const cbaResult: string = cba.foo("str"); +} + +namespace ConstructSignatures { + interface Alpha { + new(n: "str", opt?: boolean): { value: string }; + } + interface Beta { + new(n: "str", opt?: true): { value: string }; + new(n: string): { value: number | string }; + } + declare let value: Alpha | Beta; + declare let reversed: Beta | Alpha; + const result: string = new value("str").value; + const reversedResult: string = new reversed("str").value; + // @ts-expect-error + new value(1); +} + +namespace MergedDeclarations { + interface Alpha { + foo(n: string, opt?: unknown): string; + } + interface Beta { + foo(n: string, opt?: { a?: string }): string; + } + interface Beta { + foo(n: string): number; + } + declare let beta: Beta; + declare let value: Alpha | Beta; + const direct: number = beta.foo("str"); + const result: string | number = value.foo("str"); + // @ts-expect-error + const unsafeNarrow: string = value.foo("str"); +} +