Reputation: 1459
There are many examples on typing reducer functions, but they seem too verbose for my liking. I tried to keep it short and simple and wrote my actions and reducer typings as follows:
interface Actions {
VISIBLE: "yes" | "no"
LOCATION: { x: number; y: number }
}
interface Action<T extends keyof Actions> {
type: T
payload: Actions[T]
}
Type intellisense for the payload perfectly for the following example:
const example : Action<'VISIBLE'> = {type: 'VISIBLE', payload: 'yes'}
However, in the following reducer function, even when the type of the action is clear, the type of the payload is not inferred as I expected:
const myReducer = (
state: any,
action: Action<keyof Actions>
) => {
switch (action.type) {
case 'VISIBLE':
const example = action.payload
}
}
I expected the type of example
here to be inferred as 'yes' | 'no'
but instead the inference is the union of the payloads of all actions:
What am I missing here in order to make payload type inference work?
Upvotes: 0
Views: 116
Reputation: 3823
You can try
interface Actions {
VISIBLE: "yes" | "no"
LOCATION: { x: number; y: number }
}
interface Action<T extends keyof Actions> {
type: T
payload: Actions[T]
}
// Add custom typings here
type A = {
[K in keyof Actions] : Action<K>
}[keyof Actions]
const myReducer = (
state: any,
action: A
) => {
switch (action.type) {
case 'VISIBLE' :
const example = action.payload
}
}
Upvotes: 1