How can I correctly type the following:
type Events = 'DATA' | 'ABC' | 'DEF'
type PayloadMap = {
DATA: { x: number }
ABC: { y: string }
DEF: null
}
export type Handlers<E extends string, P extends Record<E, any>> = {
[event in E]?: (payload: P[E]) => any
}
const handlers: Handlers<Events, PayloadMap> = {
DATA: (payload) => {
// ERROR: Property 'x' does not exist on type '{ x: number; } | { y: string; } | null'.
const { x } = payload;
console.log(x)
return null
}
}
I would expect the payload scoped to DATA: to resolve as the single variant { x: number }. How can I achieve this without breaking up the creation of handlers into multiple steps?
>Solution :
Your Handlers type is incorrect, because it would allow the call
handlers.DATA?.({ y: "Hello "});
without error, which is why you’re getting an error in DATA:
The correct definition, given what you want, is
export type Handlers<E extends string, P extends Record<E, any>> = {
[event in E]?: (payload: P[event]) => any
}