Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to define combinations in typescript for function with switch-statement for useReducer in React?

I am using the useReducer React Hook like shown in this Video. I adapted it to my needs and it works. But because I am using Typescript, I am wondering if it is possible to define what combination can be put into the function. I have following code (very simplified):

interface actionType {
    type: string,
    payload: {
        count?: number,
        first?: number,
        second?: number,
        nameOfPerson?: string,
        message?: string
    }
}
const ACTIONS = {
    ADD_ONE: 'addOne',
    MULTIPLY: 'multiply',
    ADD_TOGETHER: 'addTogether',
}
const theFuntion = (action: actionType) => {
    const { type, payload } = action
    switch (type) {
        case ACTIONS.ADD_ONE: {
            const result: number = payload.count + 1
            return result;
        };
        case ACTIONS.MULTIPLY: {
            const result: number = payload.first * payload.second
            return result;
        };
        case ACTIONS.ADD_TOGETHER: {
            const result: string = payload.nameOfPerson + payload.message
            return result;
        };
    }
}

Following works:

theFuntion({ type: ACTIONS.ADD_ONE, payload: { count: 9 } }) // works

theFuntion({ type: ACTIONS.MULTIPLY, payload: { first: 3, second: 5 } }) // works

theFuntion({ type: ACTIONS.ADD_TOGETHER, payload: { nameOfPerson: 'Peter', message: 'Hello Wolrd!' } }) // works

These will and should not work, but does not show type error’s:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

theFuntion({ type: ACTIONS.MULTIPLY, payload: { count: 9 } })

theFuntion({ type: ACTIONS.ADD_TOGETHER, payload: { first: 3, second: 5 } })

theFuntion({ type: ACTIONS.ADD_ONE, payload: { nameOfPerson: 'Peter', message: 'Hello Wolrd!' } })

So my question is if there is a way to define an interface or something else to show me if I make a combination error when coding, because my code is ‘original code’ is way more complex and if I continue to add even more ACTIONS than I currently have (not just 3 like in my example) it will get hard to keep things in order and not get surprised while testing with ‘undefined’.

Probably unimportant, but the function should be for the useReducer React Hook and would look something like this:

export const reducerFuntion = (state: stateType, action: typeForActionsType) => {
    ...
}

>Solution :

You’ll need a discriminated union for that !

type ActionType = 'AddOne' | 'Multiply' | 'AddTogether'

type AddOne = { type: 'AddOne', payload: { count: number } }
type Multiply = { type: 'Multiply', payload: { first: number, second: number } }
type AddTogether = { type: 'AddTogether', payload: { nameOfPerson: string, message: string } }

type Action = AddOne | Multiply | AddTogether;

const theFuntion = (action: Action) => {
  switch (action.type) {
    case "AddOne": {
      const result: number = action.payload.count + 1
      return result;
    };
    case "Multiply": {
      const result: number = action.payload.first * action.payload.second
      return result;
    };
    case "AddTogether": {
      const result: string = action.payload.nameOfPerson + action.payload.message
      return result;
    };
  }
}

theFuntion({ type: "AddOne", payload: { count: 9 } }) // works

theFuntion({ type: "Multiply", payload: { first: 3, second: 5 } }) // works

theFuntion({ type: "AddTogether", payload: { nameOfPerson: 'Peter', message: 'Hello Wolrd!' } }) // works


// These show an error 

theFuntion({ type: "Multiply", payload: { count: 9 } })

theFuntion({ type: "AddTogether", payload: { first: 3, second: 5 } })

theFuntion({ type: "AddOne", payload: { nameOfPerson: 'Peter', message: 'Hello Wolrd!' } })

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading