Search code examples
reactjstypescriptreduxredux-toolkit

Can't declare initial ReduxToolkit slice state with TypeScript


There is an official documentation, that I follow to create slice with TS -> RTK usage with TS, which describes how we can give type for our state.

enter image description here

But when you do so, there is a problem in my reducers, they expect my state to contain only status key, but not data.

enter image description here

enter image description here

What am I missing here? There is a demo, where you can see the problem.


Solution

  • This is a general problem regarding TypeScript union types, as your first option { status: 'loading' } does not have a data property. You can get rid of this particular error, Property 'data' does not exist on type, by including data?: never.

    type SliceState = { state: 'loading'; data?: never } | { state: 'finished'; data: string }
    

    But you will continue to have problems. Here's why:

    Your union type says that the values of state and data must match. You cannot directly assign to either property because you risk creating an invalid state which does not meet the constraints of the union.

    If the value of your state variable is { state: 'loading' }, then assigning state.data = action.payload will create a new value of { state: 'loading'; data: 'some string' } which is not assignable to SliceState.

    You have a few options here:

    1. Use a less restrictive state type, for example:
    type SliceState = { state: 'loading' | 'finished'; data?: string };
    
    1. Use an as assertion, for example:
    (state as any).data = action.payload;
    
    1. Return a new state from your reducer rather than modifying the draft. This way you ensure that the state meets the constraints of the union type.
    dataReceived: (state, action) => {
       return { state: 'finished, data: action.payload };
    }