Skip to content

Commit

Permalink
Cherry-pick PR #42943 into release-4.2 (#42964)
Browse files Browse the repository at this point in the history
Component commits:
361e19b Ensure no duplicates in named union list

6150504 Add regression test

Co-authored-by: Anders Hejlsberg <andersh@microsoft.com>
  • Loading branch information
typescript-bot and ahejlsberg committed Feb 25, 2021
1 parent 822cb3a commit 08ad0e2
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Expand Up @@ -13403,7 +13403,7 @@ namespace ts {
if (t.flags & TypeFlags.Union) {
const origin = (<UnionType>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, (<UnionType>origin).types);
Expand Down
29 changes: 29 additions & 0 deletions tests/baselines/reference/unionOfEnumInference.js
@@ -0,0 +1,29 @@
//// [unionOfEnumInference.ts]
// Repro from #42932

enum Enum { A, B, C }

interface Interface<T extends Enum> {
type: T;
}

function foo<T extends Enum>(x: Interface<T>) { }

function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
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);
}
44 changes: 44 additions & 0 deletions 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<T extends Enum> {
>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<T extends Enum>(x: Interface<T>) { }
>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<Enum.A | Enum.B> | Interface<Enum.C>) {
>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))
}

31 changes: 31 additions & 0 deletions 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<T extends Enum> {
type: T;
>type : T
}

function foo<T extends Enum>(x: Interface<T>) { }
>foo : <T extends Enum>(x: Interface<T>) => void
>x : Interface<T>

function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
>bar : (x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) => void
>x : Interface<Enum.A | Enum.B> | Interface<Enum.C>
>Enum : any
>Enum : any
>Enum : any

foo(x);
>foo(x) : void
>foo : <T extends Enum>(x: Interface<T>) => void
>x : Interface<Enum.A | Enum.B> | Interface<Enum.C>
}

15 changes: 15 additions & 0 deletions tests/cases/compiler/unionOfEnumInference.ts
@@ -0,0 +1,15 @@
// @strict: true

// Repro from #42932

enum Enum { A, B, C }

interface Interface<T extends Enum> {
type: T;
}

function foo<T extends Enum>(x: Interface<T>) { }

function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
foo(x);
}

0 comments on commit 08ad0e2

Please sign in to comment.