Description
TypeScript Version: 3.1.2
Expected behavior:
TS should not allow us to use a value instead of a type as argument to Generic (it is a type error)
(e.g - see code below - IType<E.a>
should error. Only IType<E>
is correct for E.a
is not a type but a value of type E
)
Actual behavior:
TS treats value of an enum like a type when fed to Generic. It results in type inference problems (see the example below)
Code
enum E {
a = 'a',
b = 'b',
}
interface IType<T> {
type: T
}
interface IArrayA {
listOfTypeA: Array<IType<E.a>>
}
interface IArrayB {
listOfTypeB: Array<IType<E.b>>
}
const a: IArrayA = {
listOfTypeA: [{type: E.a}],
}
const b: IArrayB = {
listOfTypeB: a.listOfTypeA.map(() => ({type: E.b})), // ERROR: Type 'E' is not assignable to type 'E.b'.
}
Error explanation:
Ofc TS's type inference infers that {type: E.b}
is of type {type: E}
as it should. From that it infers b: {listOfTypeB: Array<{type: E}>}
. But we wanted b: {listOfTypeB: Array<{type: E.b}>}
.
Workaround: You can override TS's type system and tell it that E.b is of type E.b (although E.b is not a type...)
listOfTypeB: a.listOfTypeA.map(() => ({type: E.b as E.b})),