Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type declaration doesn't allow for none default action types #33

Open
arbassett-qnx opened this issue Jul 17, 2019 · 2 comments
Open

Type declaration doesn't allow for none default action types #33

arbassett-qnx opened this issue Jul 17, 2019 · 2 comments

Comments

@arbassett-qnx
Copy link

if the reducer uses a type for action that isn't the base redux Action typescript can't resolve what overload to use

given the reducer

import reduceReducers from 'reduce-reducers';
import { Action } from 'redux';

const ADD = 'ADD';
const MUL = 'MUL';

interface State {
  value: number;
}

interface AddAction extends Action<typeof ADD> {
  value: number;
}

interface MulAction extends Action<typeof MUL> {
  value: number;
}

const initialState: State = { value: 0 };

const addReducer = (state: State, action: AddAction): State => {
  switch (action.type) {
    case ADD: {
      return { value: state.value + action.value };
    }
    default: {
      return state;
    }
  }
};

const mulReducer = (state: State, action: MulAction): State => {
  switch (action.type) {
    case MUL: {
      return { value: state.value + action.value };
    }
    default: {
      return state;
    }
  }
};

const reducer = reduceReducers(initialState, addReducer, mulReducer);

typescript reports on initialState
Argument of type 'State' is not assignable to parameter of type 'Reducer<State>'. Type 'State' provides no match for the signature '(state: State, action: Action): State'.ts(2345)

even changing the AddAction & MulAction interface to

interface AddAction {
  type: string;
  value: number;
}

interface MulAction {
  type: string;
  value: number;
}

results in the same error

i haven't found a solution to the types but a workaround is to cast the reducers to the default reducer

const reducer = reduceReducers(initialState, addReducer as Reducer<State>, mulReducer as Reducer<State>);

this was tested in typescript 3.5.0 3.5.2 & 3.5.3
typescript doesn't report the error with "strict"=false

@teneko
Copy link

teneko commented Nov 26, 2019

Yes, the definitions really need to be updated:

declare module 'reduce-reducers' {
    import { Reducer, Action } from "typesafe-actions";

    export default function reduceReducers<S, A extends Action>(
        initialState: S | null,
        ...reducers: Reducer<S, A>[]
    ): Reducer<S, A>;
    export default function reduceReducers<S, A extends Action>(
        ...reducers: Reducer<S, A>[]
    ): Reducer<S, A>;
}

But not sure, if the Reducer type from the npm package typesafe-actions is the most most generic Reducer type.

nifanic added a commit to masterpage/reduce-reducers that referenced this issue Feb 17, 2020
This was referenced Feb 17, 2020
@kunalmohta
Copy link

This is really needed 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants