diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aaaefc6f316ce..6fc4b67bd7fa2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13403,7 +13403,7 @@ namespace ts { if (t.flags & TypeFlags.Union) { const origin = (t).origin; if (t.aliasSymbol || origin && !(origin.flags & TypeFlags.Union)) { - namedUnions.push(t); + pushIfUnique(namedUnions, t); } else if (origin && origin.flags & TypeFlags.Union) { addNamedUnions(namedUnions, (origin).types); diff --git a/tests/baselines/reference/unionOfEnumInference.js b/tests/baselines/reference/unionOfEnumInference.js new file mode 100644 index 0000000000000..b0afc9fe2f02e --- /dev/null +++ b/tests/baselines/reference/unionOfEnumInference.js @@ -0,0 +1,29 @@ +//// [unionOfEnumInference.ts] +// Repro from #42932 + +enum Enum { A, B, C } + +interface Interface { + type: T; +} + +function foo(x: Interface) { } + +function bar(x: Interface | Interface) { + foo(x); +} + + +//// [unionOfEnumInference.js] +"use strict"; +// Repro from #42932 +var Enum; +(function (Enum) { + Enum[Enum["A"] = 0] = "A"; + Enum[Enum["B"] = 1] = "B"; + Enum[Enum["C"] = 2] = "C"; +})(Enum || (Enum = {})); +function foo(x) { } +function bar(x) { + foo(x); +} diff --git a/tests/baselines/reference/unionOfEnumInference.symbols b/tests/baselines/reference/unionOfEnumInference.symbols new file mode 100644 index 0000000000000..a3ec42d2a505a --- /dev/null +++ b/tests/baselines/reference/unionOfEnumInference.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/unionOfEnumInference.ts === +// Repro from #42932 + +enum Enum { A, B, C } +>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0)) +>A : Symbol(Enum.A, Decl(unionOfEnumInference.ts, 2, 11)) +>B : Symbol(Enum.B, Decl(unionOfEnumInference.ts, 2, 14)) +>C : Symbol(Enum.C, Decl(unionOfEnumInference.ts, 2, 17)) + +interface Interface { +>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21)) +>T : Symbol(T, Decl(unionOfEnumInference.ts, 4, 20)) +>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0)) + + type: T; +>type : Symbol(Interface.type, Decl(unionOfEnumInference.ts, 4, 37)) +>T : Symbol(T, Decl(unionOfEnumInference.ts, 4, 20)) +} + +function foo(x: Interface) { } +>foo : Symbol(foo, Decl(unionOfEnumInference.ts, 6, 1)) +>T : Symbol(T, Decl(unionOfEnumInference.ts, 8, 13)) +>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0)) +>x : Symbol(x, Decl(unionOfEnumInference.ts, 8, 29)) +>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21)) +>T : Symbol(T, Decl(unionOfEnumInference.ts, 8, 13)) + +function bar(x: Interface | Interface) { +>bar : Symbol(bar, Decl(unionOfEnumInference.ts, 8, 49)) +>x : Symbol(x, Decl(unionOfEnumInference.ts, 10, 13)) +>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21)) +>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0)) +>A : Symbol(Enum.A, Decl(unionOfEnumInference.ts, 2, 11)) +>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0)) +>B : Symbol(Enum.B, Decl(unionOfEnumInference.ts, 2, 14)) +>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21)) +>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0)) +>C : Symbol(Enum.C, Decl(unionOfEnumInference.ts, 2, 17)) + + foo(x); +>foo : Symbol(foo, Decl(unionOfEnumInference.ts, 6, 1)) +>x : Symbol(x, Decl(unionOfEnumInference.ts, 10, 13)) +} + diff --git a/tests/baselines/reference/unionOfEnumInference.types b/tests/baselines/reference/unionOfEnumInference.types new file mode 100644 index 0000000000000..739f431b55393 --- /dev/null +++ b/tests/baselines/reference/unionOfEnumInference.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/unionOfEnumInference.ts === +// Repro from #42932 + +enum Enum { A, B, C } +>Enum : Enum +>A : Enum.A +>B : Enum.B +>C : Enum.C + +interface Interface { + type: T; +>type : T +} + +function foo(x: Interface) { } +>foo : (x: Interface) => void +>x : Interface + +function bar(x: Interface | Interface) { +>bar : (x: Interface | Interface) => void +>x : Interface | Interface +>Enum : any +>Enum : any +>Enum : any + + foo(x); +>foo(x) : void +>foo : (x: Interface) => void +>x : Interface | Interface +} + diff --git a/tests/cases/compiler/unionOfEnumInference.ts b/tests/cases/compiler/unionOfEnumInference.ts new file mode 100644 index 0000000000000..26f92804834bd --- /dev/null +++ b/tests/cases/compiler/unionOfEnumInference.ts @@ -0,0 +1,15 @@ +// @strict: true + +// Repro from #42932 + +enum Enum { A, B, C } + +interface Interface { + type: T; +} + +function foo(x: Interface) { } + +function bar(x: Interface | Interface) { + foo(x); +}