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:
TypeScript playground