Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Implicitly type an action payload by an action type
type ActionTypes = 'actionA' | 'actionB' | 'actionC' | 'actionNoPayload';
type ActionPayloads = {
actionA: { payload: number };
actionB: { payload: string };
actionC: { foo: boolean; bar: boolean };
};
type Actions = {
[key in ActionTypes]: {
type: key;
} & (key extends keyof ActionPayloads ? ActionPayloads[key] : {})
};
type Action = Actions[keyof Actions];
// Pass
const testA: Action = { type: 'actionA', payload: 1 };
const testB: Action = { type: 'actionB', payload: 'string' };
const testC: Action = { type: 'actionC', foo: true, bar: false };
const testD: Action = { type: 'actionNoPayload' };
// Fail
const testUnexpectedActionTypeError: Action = { type: 'not typed' };
const testUnexpectedPayloadError: Action = { type: 'actionNoPayload', payload: 'error' };
const testExpectedPayloadError: Action = { type: 'actionA' };
const testUnexpectedPayloadValueError: Action = { type: 'actionA', payload: 'error' };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.