0

I am trying to create function builder for item creation reducers in redux toolkit slice, since most of them look practically same:

createSomething: (
  state,
  action: PayloadAction<Omit<typeof State["something_set"][number], "id">
) => {
  const id = getId(state.something_set);

  state.something_set.push({ ... action.payload, id });
}

So without types I would like to have something like this:

function createWithId(key) {
  return (state, action) => {
    const lst = state[key];

    const id = getId(lst);

    lst.push({ ...action.payload, id });
  };
}

But I have trouble typing this function. I tried using KeysMatching<T, V> type from answer to similiar question, but while it works when literally specifying type, it fails when used by type parameter like this:

// Reference: https://stackoverflow.com/questions/55150760/how-to-write-pickbyvalue-type
type PickByValue<T, V> = Pick<
  T,
  { [K in keyof T]: T[K] extends V ? K : never }[keyof T]
>;

type KeysMatching<T, V> = {
  [K in keyof T]: T[K] extends V ? K : never;
}[keyof T];

function createWithId<T extends { id: number }>(key: KeysMatching<State, T[]>) {
  return (state: State, action: PayloadAction<Omit<T, "id">>) => {
    const lst = state[key]; // ERROR! Type KeysMatching<State, T[]> cannot be used to index type State.

    const id = getId(lst);

    lst.push({ ...action.payload, id });
  };
}

I cannot use nonparametric type, since there are differently typed lists in state. I also cannot simply use just keyof State, since not all keys holds lists.

So how can I type this function or is there some better pattern for building similiar reducers?

Matija Sirk
  • 596
  • 2
  • 15
  • Could you provide a plaintext [mre] we can paste into our own IDEs to see what you're seeing? Right now I'm just getting errors about undeclared things like `State`, `PayloadAction`, `getId`, etc. – jcalz Mar 15 '23 at 14:33
  • Look into the createEntityAdapter helper. – Linda Paiste Mar 15 '23 at 16:04

0 Answers0