jf1234
jf1234

Reputation: 215

TypeScript and Redux: Why do I need to add ` | undefined` to my Reducer state type?

Why can I not just type my reducer simply like this, without adding " | undefined" to my redux state type?

const reducer: Reducer<ReduxState> = function(state: ReduxState, action: any) ...

Extra context::::

This works OK:

export const reducer: Reducer<ReduxState | undefined> = function (
    state: ReduxState | undefined, 
    action: any
) {
    return state
}
export default reducer

However, it doesnt when taking away state parameter "undefined" from fxn:

export const reducer: Reducer<ReduxState | undefined> = function (
    state: ReduxState, 
    action: any
) {
    return state
}
export default reducer

Which gives an error of:

Type '(state: ReduxState, action: any) => ReduxState' is not assignable to type 'Reducer<ReduxState | undefined, AnyAction>'.
  Types of parameters 'state' and 'state' are incompatible.
    Type 'ReduxState | undefined' is not assignable to type 'ReduxState'.
      Type 'undefined' is not assignable to type 'ReduxState'.ts(2322)

Or this:

export const reducer: Reducer<ReduxState> = function (
    state: ReduxState | undefined, 
    action: any
) {
    return state
}
export default reducer

which gives an error msg of:

Type '(state: ReduxState | undefined, action: any) => ReduxState | undefined' is not assignable to type 'Reducer<ReduxState, AnyAction>'.
  Type 'ReduxState | undefined' is not assignable to type 'ReduxState'.
    Type 'undefined' is not assignable to type 'ReduxState'.ts(2322)

And lastly, this doesn't work either:

import {ReduxState, ReduxAction, ReduxActionType} from './types'
import {Reducer} from 'redux'

export const reducer: Reducer<ReduxState> = function (
    state: ReduxState, 
    action: any
) {
    return state
}
export default reducer

With an error msg of :

Type '(state: ReduxState, action: any) => ReduxState' is not assignable to type 'Reducer<ReduxState, AnyAction>'. Types of parameters 'state' and 'state' are incompatible. Type 'ReduxState | undefined' is not assignable to type 'ReduxState'. Type 'undefined' is not assignable to type 'ReduxState'.ts(2322)

TL; DR: Typescript isn't happy with my Reducer unless I specifically allow "ReduxState | undefined" type in both the Reducer<ReduxState|undefined> and function(state: ReduxState | undefined).

Upvotes: 7

Views: 1696

Answers (2)

hayato_777
hayato_777

Reputation: 1

maybe you should give your state a default value, like

import {ReduxState, ReduxAction, ReduxActionType} from './types'
import {Reducer} from 'redux'

const defaultState = {
    // your default state
}

export const reducer: Reducer<ReduxState> = function (
    state = defaultState, 
    action: any
) {
    return state
}
export default reducer

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138317

Because for the initial state, the previous state is undefined. Therefore your function has to be able to deal with state being undefined, thats what the first error tells you.

The second version doesn't work, because you return state, and that can be undefined (as you don't check if it is not defined), and therefore the return type of that function (which is the generic argument to Reducer) also have to be possible undefined. You could guard against that:

  if(state === undefined)
     return { /*...*/ };
  else return state;

then Reducer<ReduxState> would describe the type correctly.

Upvotes: 5

Related Questions