Let's assume we have following interfaces:
interface A {
type: 'A';
value: {
a: 3,
};
}
interface B {
type: 'B';
value: {
b: 3,
};
}
I create another interface which uses union of these interfaces:
interface C {
detail: A | B;
}
Now we should be able to detect type A
or B
using their type
property:
function test(arg: C) {
if (arg.detail.type === 'A') {
arg.detail.value.a;
} else if (arg.detail.type === 'B') {
arg.detail.value.b;
}
}
There is no error as we expected it.
Problem: Let's make another interface which has index signature:
interface cArr {
[index: string]: C;
}
I expect to detect type of values of cArr
type same as arg
variable with their type
property:
function test(arg2: cArr, ID: string) {
if (arg2[ID].detail.type === 'A') {
arg2[ID].detail.value.a;
}
}
But typescript gives me following error:
Property 'a' does not exist on type '{ a: 3; } | { b: 3; }'.
Property 'a' does not exist on type '{ b: 3; }'.
What's the problem? Why if
statement couldn't narrow down type of arg2
?
TypeScript's inference is limited when it comes to indexed properties, so just store the object whose type you want to infer in a new variable:
function test(arg2: cArr, ID: string) {
const item = arg2[ID];
if (item.detail.type === 'A') {
item.detail.value.a;
}
}