Reputation: 42
I have an object that is discriminated on the type
property which can be any value of a given enum. When I create a valid object and then pass it to a function, typescript complains that the types don't match. However, if I coerce the enum value then it's fine.
enum AorB {
A = 'a',
B = 'b',
};
type Bar_A = {
type: AorB.A;
};
type Bar_B = {
type: AorB.B;
}
type Bar = Bar_A | Bar_B;
function foo(a: Bar): void {}
const arg = {
type: AorB.A,
};
// this would work but is extra writing
// const arg = {
// type: AorB.A as AorB.A
// };
foo(arg); // Error
foo({
type: AorB.A,
})
See the equivalent playground link
Upvotes: 0
Views: 131
Reputation: 249716
Typescript will widen literal types unless it has a reason to keep them around so arg
will be typed as {type: AorB }
not { type: AorB.A, }
.
If you explicitly use a type assertion AorB.A as AorB.A
then typescript will preserve the literal type. If you assign the object literal to a location that requires Bar
(such as the parameter to the function) typescript will again preserve the literal type.
Another option that will work is to type arg
explicitly:
const arg: Bar = {
type: AorB.A,
};
foo(arg);
foo({
type: AorB.A,
})
Or use as const
in 3.4 to get the compiler to keep literal types without having to specify the type again, although that will make the whole object readonly.
Upvotes: 2