如何为Immer produce函数的复杂类型设置TypeScript类型?
解决Immer produce配合React setState的TypeScript类型问题
问题出在你混淆了Immer produce的两种调用方式,导致类型匹配失败:
Immer的produce有两种核心用法:
- 双参数形式:
produce(原始状态, 草稿修改函数),直接返回修改后的新状态 - 柯里化形式:
produce(草稿修改函数),返回一个接收原始状态并输出新状态的函数
你之前的写法错误地给柯里化形式的produce指定了泛型参数,导致TypeScript无法正确推断类型,进而把返回的函数当成了Book类型的值传给setUnsavedBook。
正确写法1:结合React setState回调+produce双参数形式
onChange={(event) => { setUnsavedBook(prevBook => produce(prevBook, draft => { draft.preface.author = event.target.value; })); }}
这里setUnsavedBook接收的是React允许的状态更新回调,拿到当前的prevBook后传给produce作为原始状态,TypeScript会自动推断所有类型,不需要额外标注。
正确写法2:直接用produce柯里化形式作为setState回调
onChange={(event) => { setUnsavedBook(produce((draft: Draft<Book>) => { draft.preface.author = event.target.value; })); }}
produce返回的函数正好符合React setState回调的类型要求((prevState: Book) => Book),只需给draft标注Draft<Book>即可(甚至可以省略,TypeScript会根据setUnsavedBook的状态类型自动推断)。
另外要确保你的Book类型定义正确,比如:
interface Book { preface: { author: string; // 其他字段... }; // 其他字段... }
内容的提问来源于stack exchange,提问作者Duskendale
相关产品推荐
相关产品推荐

