I am seeing TS type errors trying to pass state into an entityAdapter CRUD function
live sandbox (with erroneous line commented out):
https://codesandbox.io/s/createentityadapter-demo-5rvl4
create books adapater
const booksAdapter = createEntityAdapter<Book>({
selectId: (book) => book.bookId,
sortComparer: (a, b) => a.title.localeCompare(b.title)
});
...create a slice and configure store
const booksSlice = createSlice({
name: "books",
initialState: booksAdapter.getInitialState(),
reducers: {
// Can pass adapter functions directly as case reducers. Because we're passing this
// as a value, `createSlice` will auto-generate the `bookAdded` action type / creator
bookAdded: booksAdapter.addOne,
bookRemoved: booksAdapter.removeOne,
bookUpdated: booksAdapter.updateOne,
booksReceived(state, action) {
// Or, call them as "mutating" helpers in a case reducer
booksAdapter.setAll(state, action.payload.books);
}
}
});
export const store = configureStore({
reducer: {
books: booksSlice.reducer
}
});
...dispatch works as expected
store.dispatch(bookAdded({ bookId: 1, title: "title 1" }));
store.dispatch(bookAdded({ bookId: 2, title: "title 2" }));
store.dispatch(bookAdded({ bookId: 3, title: "title 3" }));
but im getting an error when i retrieve store state and try to use it in imperative call to adapter.addOne (i.e. not through the reducer)
let storeState = store.getState();
console.log("storeState", storeState, typeof storeState);
// booksAdapter.addOne(storeState, { id: 4, title: "title 4" });
console.log of the storeState looks like a valid object...
storeState
{books: Object}
books: Object
ids: Array(3)
0: 1
1: 2
2: 3
entities: Object
1: Object
2: Object
3: Object
object
but the line (commented out)
booksAdapter.addOne(storeState, { id: 4, title: "title 4" });
results in TS error:
let storeState: {
books: EntityState<Book>;
}
No overload matches this call.
Overload 1 of 2, '(state: EntityState<Book>, entity: Book): EntityState<Book>', gave the following error.
Argument of type '{ books: EntityState<Book>; }' is not assignable to parameter of type 'EntityState<Book>'.
I dont understand why there is a mismatch as I am passing the store in directly.
I have tried this in JS and of course there are no type issues and it just works. My question is then: what is the correct state object to pass in to CRUD functions when using TS if not the result of store.getState()?
The data is in
storeState.books, not instoreState.So you will need to call
note that this will not modify your state but just give you a modified copy of said state. You can modify your state only via an action dispatch.