I have a discriminating union, simplified into this example.
type FoobarEvent = FooEvent | BarEvent;
interface FooEvent {
type: 'foo';
foo: {
name: string;
}
}
interface BarEvent {
type: 'bar';
bar: {
id: string;
}
}
Of course I can check the discriminant and get the union type narrowed down properly.
// let's assume this exists
declare const foobarEvent: FoobarEvent;
let fooName: string | undefined;
if (foobarEvent.type === 'foo') {
fooName = foobarEvent.foo.name;
}
However I want to avoid this if-block, so I tried to use optional chaining to narrow down the type, but that doesn't work because one of the unions doesn't have the field I'm trying to access.
const fooNameByChaining = foobarEvent.foo?.name;
Property 'foo' does not exist on type 'FoobarEvent'.
Property 'foo' does not exist on type 'BarEvent'.
So apparently the narrowing would need to happen before the optional chaining. Is this a limitation of TypeScript's type system or could this be added to Typescript as a feature? Or is there another way around this that I'm not aware of?