I have an Actions
type that need to be mapped to a set of callbacks in the actionMap
variable.
However, I'm unsure on how to enforce type of the first generic element of the Action
type. Clearly key in keyof Actions
isn't doing the trick here. What would I need to use instead?
export interface Action<T, U> {
type: T,
data: U,
}
export type Actions =
| Action<"something", {}>
| Action<"somethingElse", {}>
const actionMap: { [key in keyof Actions]: (action: Actions) => any } = {
// I'd like the value of the `type` property of all my actions enforced here. Ex:
// "something": (action) => {}
// "somethingElse": (action) => {}
}
If I’m asking the wrong question, what is a better question? I'm not sure I'm using the jargon accordingly.
You can achieve this by using indexed access types to grab a property of the interface, and Extract
to narrow down the type of action
in the function.
export interface Action<T, U> {
type: T,
data: U,
}
export type Actions =
| Action<"something", { something: true}>
| Action<"somethingElse", { somethingElse: true }>
const actionMap: { [K in Actions['type']]: (action: Extract<Actions, { type: K }>) => any } = {
"something": (action) => {}, // TS knows action.data.something exists
"somethingElse": (action) => {} // TS knows action.data.somethingElse exists
}