Skip to content

Commit 08ad0e2

Browse files
TypeScript Botahejlsberg
TypeScript Bot
andauthored
Cherry-pick PR #42943 into release-4.2 (#42964)
Component commits: 361e19b Ensure no duplicates in named union list 6150504 Add regression test Co-authored-by: Anders Hejlsberg <andersh@microsoft.com>
1 parent 822cb3a commit 08ad0e2

File tree

5 files changed

+120
-1
lines changed

5 files changed

+120
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13403,7 +13403,7 @@ namespace ts {
1340313403
if (t.flags & TypeFlags.Union) {
1340413404
const origin = (<UnionType>t).origin;
1340513405
if (t.aliasSymbol || origin && !(origin.flags & TypeFlags.Union)) {
13406-
namedUnions.push(t);
13406+
pushIfUnique(namedUnions, t);
1340713407
}
1340813408
else if (origin && origin.flags & TypeFlags.Union) {
1340913409
addNamedUnions(namedUnions, (<UnionType>origin).types);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [unionOfEnumInference.ts]
2+
// Repro from #42932
3+
4+
enum Enum { A, B, C }
5+
6+
interface Interface<T extends Enum> {
7+
type: T;
8+
}
9+
10+
function foo<T extends Enum>(x: Interface<T>) { }
11+
12+
function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
13+
foo(x);
14+
}
15+
16+
17+
//// [unionOfEnumInference.js]
18+
"use strict";
19+
// Repro from #42932
20+
var Enum;
21+
(function (Enum) {
22+
Enum[Enum["A"] = 0] = "A";
23+
Enum[Enum["B"] = 1] = "B";
24+
Enum[Enum["C"] = 2] = "C";
25+
})(Enum || (Enum = {}));
26+
function foo(x) { }
27+
function bar(x) {
28+
foo(x);
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
=== tests/cases/compiler/unionOfEnumInference.ts ===
2+
// Repro from #42932
3+
4+
enum Enum { A, B, C }
5+
>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0))
6+
>A : Symbol(Enum.A, Decl(unionOfEnumInference.ts, 2, 11))
7+
>B : Symbol(Enum.B, Decl(unionOfEnumInference.ts, 2, 14))
8+
>C : Symbol(Enum.C, Decl(unionOfEnumInference.ts, 2, 17))
9+
10+
interface Interface<T extends Enum> {
11+
>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21))
12+
>T : Symbol(T, Decl(unionOfEnumInference.ts, 4, 20))
13+
>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0))
14+
15+
type: T;
16+
>type : Symbol(Interface.type, Decl(unionOfEnumInference.ts, 4, 37))
17+
>T : Symbol(T, Decl(unionOfEnumInference.ts, 4, 20))
18+
}
19+
20+
function foo<T extends Enum>(x: Interface<T>) { }
21+
>foo : Symbol(foo, Decl(unionOfEnumInference.ts, 6, 1))
22+
>T : Symbol(T, Decl(unionOfEnumInference.ts, 8, 13))
23+
>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0))
24+
>x : Symbol(x, Decl(unionOfEnumInference.ts, 8, 29))
25+
>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21))
26+
>T : Symbol(T, Decl(unionOfEnumInference.ts, 8, 13))
27+
28+
function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
29+
>bar : Symbol(bar, Decl(unionOfEnumInference.ts, 8, 49))
30+
>x : Symbol(x, Decl(unionOfEnumInference.ts, 10, 13))
31+
>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21))
32+
>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0))
33+
>A : Symbol(Enum.A, Decl(unionOfEnumInference.ts, 2, 11))
34+
>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0))
35+
>B : Symbol(Enum.B, Decl(unionOfEnumInference.ts, 2, 14))
36+
>Interface : Symbol(Interface, Decl(unionOfEnumInference.ts, 2, 21))
37+
>Enum : Symbol(Enum, Decl(unionOfEnumInference.ts, 0, 0))
38+
>C : Symbol(Enum.C, Decl(unionOfEnumInference.ts, 2, 17))
39+
40+
foo(x);
41+
>foo : Symbol(foo, Decl(unionOfEnumInference.ts, 6, 1))
42+
>x : Symbol(x, Decl(unionOfEnumInference.ts, 10, 13))
43+
}
44+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/compiler/unionOfEnumInference.ts ===
2+
// Repro from #42932
3+
4+
enum Enum { A, B, C }
5+
>Enum : Enum
6+
>A : Enum.A
7+
>B : Enum.B
8+
>C : Enum.C
9+
10+
interface Interface<T extends Enum> {
11+
type: T;
12+
>type : T
13+
}
14+
15+
function foo<T extends Enum>(x: Interface<T>) { }
16+
>foo : <T extends Enum>(x: Interface<T>) => void
17+
>x : Interface<T>
18+
19+
function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
20+
>bar : (x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) => void
21+
>x : Interface<Enum.A | Enum.B> | Interface<Enum.C>
22+
>Enum : any
23+
>Enum : any
24+
>Enum : any
25+
26+
foo(x);
27+
>foo(x) : void
28+
>foo : <T extends Enum>(x: Interface<T>) => void
29+
>x : Interface<Enum.A | Enum.B> | Interface<Enum.C>
30+
}
31+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @strict: true
2+
3+
// Repro from #42932
4+
5+
enum Enum { A, B, C }
6+
7+
interface Interface<T extends Enum> {
8+
type: T;
9+
}
10+
11+
function foo<T extends Enum>(x: Interface<T>) { }
12+
13+
function bar(x: Interface<Enum.A | Enum.B> | Interface<Enum.C>) {
14+
foo(x);
15+
}

0 commit comments

Comments
 (0)