Reputation: 2158
How would I achieve type inference in the following case:
type a = {
foo: number;
bar: string;
}
type b = {
foo: string;
}
let baz: a | b;
if (baz.foo === 5) {
baz.bar = "abc"; // baz type is still a | b, should be a
}
Upvotes: 1
Views: 177
Reputation: 13954
Apparently types cannot be inferred from the types of their properties, so you will need to define a type guard:
type a = {
foo: number;
bar: string;
}
type b = {
foo: string;
}
let baz: a | b;
function isA(x: a | b): x is a {
return typeof x.foo === 'number';
}
if (isA(baz) && baz.foo === 5) {
baz.bar = "123";
}
The isA
type guard will tell TypeScript that you have checked baz
s type yourself. Below is another way to achieve this with casts, but here you still need to cast baz
for every usage which is probably not the best way to do this.
if ((baz as a).foo === 5) {
(baz as a).z = "123";
}
More information about type guards can be found in the TypeScript docs.
Upvotes: 2
Reputation: 42270
baz type is still a | b, should be a
Actually what the TypeScript compiler does is restricts property access of all unified types (a | b
) to properties that exist on all of them, thus, baz.bar
does not even compile because bar
does not exist on type b
.
Upvotes: 0