reactjsreduxredux-toolkitcreateentityadapter

ReduxToolikt entity adapter question: how do i define the selectId type for update?


I am learning how to use createEntityAdapter in a working example and I can't resolve the selectId for Update functions correctly.

Working sandbox: https://codesandbox.io/s/createentityadapter-demo-forked-5rvl4

The entityAdapter is initialised as:

const entityAdapter = createEntityAdapter<Book>({
  selectId: (book) => book.bookId,
  sortComparer: (a, b) => a.title.localeCompare(b.title)
});

Adding values works ok:

const stateOne = entityAdapter.addOne(initialState, {
  bookId: 1,
  title: "hello"
});

const stateTwo = entityAdapter.addMany(stateOne, [
  { bookId: 2, title: "two" },
  { bookId: 3, title: "three" },
  { bookId: 4, title: "four" }
]);

However updateOne gives type error on the bookId:

const stateThree = entityAdapter.updateOne(stateTwo, {
  bookId: 3,
   changes: {
     title: "three - change"
   }
});

TS error:

(property) bookId: number No overload matches this call. Overload 1 of 2, '(state: EntityState, update: Update): EntityState', gave the following error. Argument of type '{ bookId: number; changes: { title: string; }; }' is not assignable to parameter of type 'Update'. Object literal may only specify known properties, and 'bookId' does not exist in type 'Update'. Overload 2 of 2, '(state: EntityState, update: { payload: Update; type: string; }): EntityState', gave the following error. Argument of type '{ bookId: number; changes: { title: string; }; }' is not assignable to parameter of type '{ payload: Update; type: string; }'. Object literal may only specify known properties, and 'bookId' does not exist in type '{ payload: Update; type: string; }'.ts(2769)

Why am I seeing this error when I have explicitly defined bookId as my select Id?


Solution

  • For the update* methods, the action payload must be an object that has fields exactly named id and changes, regardless of what the actual ID field is in your data types. So, this should work correctly:

    const stateThree = entityAdapter.updateOne(stateTwo, {
      id: 3,
       changes: {
         title: "three - change"
       }
    });