redux-toolkit icon indicating copy to clipboard operation
redux-toolkit copied to clipboard

State argument on createSlice is no longer inferred with typescript beta 4.8 and they do not plan to fix it

Open lukeapage opened this issue 2 years ago • 5 comments

See the bug on the typescript repo: https://github.com/microsoft/TypeScript/issues/49307#issuecomment-1195031370

It seems the typescript team will not fix this. Maybe the redux-toolkit types can be fixed to be compatible and still infer? else the examples and documentation need changing to say that the state argument will not be inferred and need to be explicitly provided.

cc/ @markerikson

lukeapage avatar Jul 26 '22 05:07 lukeapage

Hmm. @phryneas , you know way more about the createSlice types than I do - any ideas?

markerikson avatar Jul 26 '22 05:07 markerikson

In trying to fix this, I've discovered that even in strict mode, nothing enforces that the payload argument of a slice is typed - and it defaults to any. And in trying to fix that, even on 4.7, it ends up requiring the user to type not just the action parameter but the state one too.

lukeapage avatar Jul 26 '22 06:07 lukeapage

Essentially, it breaks ValidateSliceCaseReducers. That's not gonna be fun.

phryneas avatar Jul 26 '22 06:07 phryneas

For historical context why that type is there: https://github.com/reduxjs/redux-toolkit/pull/149#issuecomment-515787522

phryneas avatar Jul 26 '22 06:07 phryneas

btw I worked out how to enforce a payload type is always provided:

export type ValidateSliceCaseReducers<S, ACR extends SliceCaseReducers<S>> = ACR & {
    [T in keyof ACR]: ACR[T] extends {
        reducer(s: S, action?: infer A): any;
    }
        ? A extends PayloadAction<any>
            ? CaseReducerWithPrepare<S, A>
            : never
        : ACR[T] extends CaseReducer<S, PayloadAction<EmptyObject>>
        ? (state: S) => S
        : CaseReducer<S, PayloadAction<any>>;

For ts 4.7, I think it does the same enforcement that prepare actions match, it does not require a typed state argument and it enforces that the payload can never be any, unknown or a empty object (but the argument can be missing).

Since it forces typing actions on everyone using typescript, I don't know if you want to include it.

Unfortunately though, it does not help with the infer of the state argument in 4.8.

lukeapage avatar Jul 26 '22 07:07 lukeapage

Either we fixed this or it isn't enough of an issue that people are complaining :)

markerikson avatar Aug 16 '23 16:08 markerikson