Reputation: 2279
I'm trying to use Immer with my react project which is already using Typescript. I couldn't find in the docs, or anywhere else, how to actually use immer with typescript.
What I have so far:
export interface IProps { }
export interface IState {
names: string[]
}
export class ListNames extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props)
this.state = { names: [] }
}
addName = (name: string) => {
this.setState(produce(draftState => {
draftState.names.push(name)
}))
}
...
}
this gives me two errors:
[ts] Object is possibly 'null'
[ts] Property 'names' does not exist on type 'DraftObject<Pick<IState, never>>'
Setting the type for draftState
to IState
won't work. What I've done that made it work was to cast the draftState
to IState
before I use it.
The thing is: I might want to use draftState more than one time, so it is at least inconvenient.
What's the correct way to use Immer with Typescript?
Upvotes: 7
Views: 11521
Reputation: 191729
Looking at the type definition for produce
, it takes a generic type that is the state which defaults to any
. Your TypeScript rules are set up in such a way that it thinks draftState
could be null. You can specify the generic type to produce
to specify what the state is:
produce<IState>(draftObject ...
Upvotes: 11