From d86ec94be03ad9b648a2ea86998c5be23e82743c Mon Sep 17 00:00:00 2001 From: Ben Durrant Date: Tue, 4 Jun 2024 11:43:52 +0100 Subject: [PATCH] Tweak TS usage docs for createEntityAdapter --- docs/usage/usage-with-typescript.md | 36 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/docs/usage/usage-with-typescript.md b/docs/usage/usage-with-typescript.md index 6d2dd15750..de288f33d3 100644 --- a/docs/usage/usage-with-typescript.md +++ b/docs/usage/usage-with-typescript.md @@ -724,20 +724,46 @@ Import and use that pre-typed `createAppAsyncThunk` instead of the original, and ## `createEntityAdapter` -Typing `createEntityAdapter` only requires you to specify the entity type as the single generic argument. +Usage of `createEntityAdapter` with Typescript varies based on whether your entities are normalized by an `id` property, or whether a custom `selectId` is needed. -The example from the `createEntityAdapter` documentation would look like this in TypeScript: +If your entities are normalized by an `id` property, `createEntityAdapter` only requires you to specify the entity type as the single generic argument. For example: ```ts interface Book { - bookId: number + id: number title: string - // ... } +// no selectId needed here, as the entity has an `id` property we can default to // highlight-next-line const booksAdapter = createEntityAdapter({ - selectId: (book) => book.bookId, + sortComparer: (a, b) => a.title.localeCompare(b.title), +}) + +const booksSlice = createSlice({ + name: 'books', + initialState: booksAdapter.getInitialState(), + reducers: { + bookAdded: booksAdapter.addOne, + booksReceived(state, action: PayloadAction<{ books: Book[] }>) { + booksAdapter.setAll(state, action.payload.books) + }, + }, +}) +``` + +On the other hand, if the entity needs to be normalized by a different property, we instead recommend passing a custom `selectId` function and annotating there. This allows proper inference of the ID's type, instead of having to provide it manually. + +```ts +interface Book { + bookId: number + title: string + // ... +} + +const booksAdapter = createEntityAdapter({ + // highlight-next-line + selectId: (book: Book) => book.bookId, sortComparer: (a, b) => a.title.localeCompare(b.title), })