DEV Community

Discussion on: UseReducer With Typescript

Collapse
torbenrahbekkoch profile image
Torben Rahbek Koch

You may want to look into discriminated unions : typescriptlang.org/docs/handbook/a...

The syntax is, I think, somewhat clunky, but the idea is that you start out with an enum with your action types:

enum Kind {
    ShowAll,
    SetStatus
}
Enter fullscreen mode Exit fullscreen mode

Then the actual discriminated union with whatever data each action type needs:

type Action = {
    kind : Kind.ShowAll
    payload : boolean
}
| {
    kind : Kind.SetStatus
    index : number
    status : string
}
Enter fullscreen mode Exit fullscreen mode

In your reducer you can now switch on kind:

function stepsReducer(steps: IFormStep[], action: Action) {
    switch (action.Kind)
    {
        case Kind.ShowAll:
            // You can now access action.payload  and do whatever...
            break;
         case Kind.SetStatus:
             // You can now access action.index and action.status
             break;
          default:
              // This mostly seems like black magic to me, but it has the compiler
              // warn when you have NOT switched on ALL action types:
              const _exhaustiveCheck: never = action;
        }
}
Enter fullscreen mode Exit fullscreen mode

It is fairly elegant, although perhaps a bit convoluted, but you have the compiler help you out quite bit :)

Collapse
stephencweiss profile image
Stephen Charles Weiss Author

Very nice! Thank you!