Skip to content

Incorrect type inference for a union of an enum type and an enum value #22093

@eebbing

Description

@eebbing

TypeScript Version: 2.8.0-dev.20180221
Search Terms: union type enum generic type inference TS2322

Code

enum A { one = "one", two = "two" };
enum B { foo = "foo", bar = "bar" };

type C = A | B.foo;
type D = A | "foo";

class List<T>
{
	private readonly items: T[] = [];
}

function asList<T>(arg: T): List<T> { return new List(); }

// TypeScript incorrectly infers the return type of "asList(x)" to be "List<A | B>"
// The correct type is "List<A | B.foo>"
function fn1(x: C): List<C> { return asList(x); }

// If we use the literal "foo" instead of B.foo, the correct type is inferred
function fn2(x: D): List<D> { return asList(x); }

Expected behavior:
Typescript should infer that asList(x) in fn1() returns a List<C> or List<A | B.foo> instead of List<A | B>.

Actual behavior:
The tsc compiler shows the following error:

error TS2322: Type 'List<A | B>' is not assignable to type 'List<C>'.
    Type 'A | B' is not assignable to type 'C'.
        Type 'B.bar' is not assignable to type 'C'.

Playground Link

Related Issues:
This same issue also occurs when the generic type argument of the constructor is inferred from the type of the variable on the left hand side of the assignment. Example:

enum A { one = "one", two = "two" };
enum B { foo = "foo", bar = "bar" };

type C = A | B.foo;
type D = A | "foo";

class List<T>
{
	private readonly items: T[] = [];
}

function fn()
{
	let a: List<C>;
	let b: List<D>;

	a = new List(); // <-- this is where the TS2322 error pops up
	b = new List();
}

Playground Link

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions