Imagine you have following TS code:
enum stores {
book,
chapter,
verse
}
const reducer = {
[stores.book]: { a: 'string', b: 1 },
[stores.chapter]: { a: 'string', c: 2 },
[stores.verse]: { a: 'string', d: false }
}
function main ({
storeName,
getA
}:{
storeName: stores,
getA: (item: typeof reducer[stores]) => void
}) {
const item = reducer[storeName]
getA(item)
return
}
main({storeName: stores.verse, getA(item) {
item.a // only can get common a attribute, but
item.d // can't get special for stores.verse attribute
}})
What should I do to make typescript dynamically understand type of item in getA depending on storeName and reducer?
Working on my React-Redux app rn. I want to make generic component for multiple Redux slices. The API inside component consists only of common attributes, so it's fine and working, but I need to get exact type of object in slice in one of props functions
The compiler needs to keep track of the specific member of stores
which was used to call the function. This can be achieved by declaring a generic type parameter S
and using it to type storeName
.
The type of the value passed as storeName
will be used to infer the type of S
. The parameter item
can be typed as typeof reducers[S]
.
function main<S extends stores>({
storeName,
getA,
}: {
storeName: S;
getA: (item: typeof reducer[S]) => void;
}) {
const item = reducer[storeName];
getA(item);
return;
}
The type of the parameter item
now depends on the enum member passed as storeName
.
main({
storeName: stores.verse,
getA(item) {
// ^? item: { a: string; d: boolean; }
item.a;
item.d;
},
});
main({
storeName: stores.book,
getA(item) {
// ^? item: { a: string; b: number; }
item.a;
item.b;
},
});