如何让TypeScript正确识别React Hooks中setState的回调参数?
问题根因
你写的setChips类型存在运算符优先级解析错误:TypeScript 会把(newChips: Array<ChipsData>) => void | ((setCallback: (previousState: ChipsData[]) => ChipsData[]) => void)解析为:
- 函数仅接收
ChipsData[]类型的入参 - 返回值是
void,或者是一个接收回调的函数
完全不符合「setChips本身支持两种入参格式」的预期,所以TS无法识别传回调的调用分支。
修正方法
要让setChips同时支持「直接传入新数组」「传入基于旧状态计算新值的回调」两种入参,需要把入参类型定义为联合类型,函数整体返回值固定为void,修正后的类型定义如下:
type ChipsContextData = { chips: Array<ChipsData>; // 核心修正:将两种入参类型做联合,作为setChips的参数类型 setChips: (newChips: ChipsData[] | ((previousState: ChipsData[]) => ChipsData[])) => void; counters: Array<number>; setCounters: (newCounters: Array<number> | ((previousState: number[]) => number[])) => void; }
更简洁的写法(React场景适用)
如果这个类型是为React Context定义的,可以直接复用React内置的状态setter类型,和useState返回的更新函数类型完全一致,不需要手动写联合:
import type { Dispatch, SetStateAction } from 'react'; type ChipsContextData = { chips: ChipsData[]; setChips: Dispatch<SetStateAction<ChipsData[]>>; counters: number[]; setCounters: Dispatch<SetStateAction<number[]>>; }
修正后两种调用方式都能被TS正确校验:
// 直接传新值 setChips([{ /* 新的chips数据 */ }]); // 传回调基于旧状态更新 setChips(prev => [...prev, { /* 新增的chip数据 */ }]);
内容的提问来源于stack exchange,提问作者Gentil Alyson
相关产品推荐
相关产品推荐

