So I have a variant of question that was asked before but somehow non of the answers help. Here's the code:
type ModelA = {
type: 'a'
method: 'foo' | 'bar'
}
type ModelB = {
type: 'b'
method: 'baz'
}
type Model = ModelA | ModelB
const dictionary = {
a: {
foo: () => 'foo',
bar: () => 'bar'
},
b: {
baz: () => 'baz'
}
}
function getMethod(m: Model): Function {
return dictionary[m.type][m.method] <--- error
}
Element implicitly has an 'any' type because expression of type '"foo" | "bar" | "baz"' can't be used to index type '{ foo: () => string; bar: () => string; } | { baz: () => string; }'.
Property 'foo' does not exist on type '{ foo: () => string; bar: () => string; } | { baz: () => string; }'.
If I use some silly type check like this:
function getMethod(m: Model) {
if (m.type === 'a') {
return dictionary[m.type][m.method]
}
return dictionary[m.type][m.method]
}
it works because that in both branches TS knows that it's safe to get the method.
I know this should be solved using generic but somehow I can't figure out.