question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Why "createReducer" return type isn't a deox/dist/types/Reducer?

See original GitHub issue

For those who received a incomplete issue in email, I am sorry, I have hit enter accidentally before finishing.

Now, to the issue:

I am trying to pass a Reducer as a parameter to a method, but I get a compile error about the types.

Please let me know if I am using the library wrong:

Error:(61, 27) TS2345: Argument of type ‘(state: DeepImmutableArray<Param> | undefined, action: { type: string; payload: Param; } | { type: string; payload: { index: number; param: Param; }; } | { type: string; payload: { fromIndex: number; toIndex: number; }; }) => Param[] | DeepImmutableArray<…>’ is not assignable to parameter of type ‘Reducer<DeepImmutableArray<Param>, { type: string; payload: Param; } | { type: string; payload: { index: number; param: Param; }; } | { type: string; payload: { fromIndex: number; toIndex: number; }; }>’. Types of parameters ‘state’ and ‘prevState’ are incompatible. Property ‘[Symbol.iterator]’ is missing in type ‘DeepImmutableObject<DeepImmutableArray<Param>>’ but required in type ‘DeepImmutableArray<Param>’.

export function createParamTableReducer(
  actions: ParamTableActionCreators
): Reducer<Param[]> {
  const deoxReducer = createReducer([] as Param[], (handle) => [
    handle(actions.addParam, (state, { payload }) =>
      produce(state, (draft: Draft<Param[]>) => {
        draft.push(payload);
      })
    ),
    handle(actions.removeParam, (state, { payload }) =>
      produce(state, (draft: Draft<Param[]>) => {
        draft.splice(payload.index, 1);
      })
    ),
    handle(actions.updateParam, (state, { payload }) =>
      produce(state, (draft: Draft<Param[]>) => {
        draft[payload.index] = payload.param;
      })
    ),
    handle(actions.reorderParams, (state, { payload }) =>
      produce(state, (draft: Draft<Param[]>) => {
        draft.splice(payload.fromIndex, 1);
        draft.splice(payload.toIndex, 0, state[payload.fromIndex]);
      })
    ),
  ]);

  return normalizeReducer(deoxReducer);
}
import { Reducer } from "deox/dist/types";
import { Action, Reducer as ReduxReducer } from "redux";

export function normalizeReducer<T, A extends Action>(
  deoxReducer: Reducer<T, A>
): ReduxReducer<T, A>

Why doesn’t “createReducer” uses the existing Reducer type as a returnType?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:19 (19 by maintainers)

github_iconTop GitHub Comments

1reaction
LouizFCcommented, May 28, 2019

That is exactly what I was looking for. I am not a “typescript expert” so I have not yet understood the infer keyword completely.

Your example made it clear in my mind, Thank you very much

1reaction
the-dr-lazycommented, May 28, 2019

If we were to make the return type of createReducer explicit using the DeoxReducer above, how would be it declared?

It should be declared like how Action type was declared. By inferring the return type of HandlerMap(s).

type HandlerMap<TPrevState, TAction, TNextState extends TPrevState> = {
  [type in TAction['type']]: Handler<TPrevState, TAction, TNextState>
}

export type InferActionFromHandlerMap<
  THandlerMap extends HandlerMap<any, any, any>
> = THandlerMap extends HandlerMap<any, infer T, any> ? T : never

export type InferNextStateFromHandleMap<
  THandlerMap extends HandlerMap<any, any, any>
> = THandlerMap extends HandlerMap<any, any, infer T> ? T : never

function createReducer<
  TPrevState,
  THandlerMap extends HandlerMap<TPRevState, any, any>
>(
  defaultState: TPrevState,
  handlerMapsCreator: (handle: CreateHandlerMap<TPrevState>) => THandlerMap[]
) {
  // ...

 return (
    state = defaultState,
    action: InferActionFromHandlerMap<THandlerMap>
  ): InferNextStateFromHandleMap<THandlerMap> => {
    // ...
  }
}

I hope I understood your question correctly. If not, excuse me for my bad English and please ask your question with more details.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why "createReducer" return type isn't a deox/dist ... - GitHub
Now, to the issue: I am trying to pass a Reducer as a parameter to a method, but I get a compile error...
Read more >
createReducer - Redux Toolkit
A utility that simplifies creating Redux reducer functions. It uses Immer internally to drastically simplify immutable update logic by writing " ...
Read more >
Redux actions typescript return type not working
So basicly I am trying to return types for a set of functions & being able to match that in my redux reducer....
Read more >
Reducing the Reducer Boilerplate With createReducer()
This article is a short and simple walk-through for reducing the reducer boilerplate by using a more functional approach.
Read more >
Error A case reducer on a non-draftable value must not return ...
I'm trying to import typescript in my redux application. I use redux toolkit createSlice ... = modeSlice.actions; export default ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found