TypeScript中useState的setter函数如何定义正确类型?
useState setter函数的TypeScript正确标注方式
useState 返回的状态更新函数(setter)有官方内置的标准类型,不需要手动自定义函数类型,通用写法完全适配所有状态场景。
标准官方写法
React 直接导出了对应类型,泛型参数和你传入useState的状态泛型保持一致即可:
- 类型组成:
Dispatch<SetStateAction<T>>- 泛型
T:和useState<T>的泛型参数完全相同,对应状态的类型 - 这个类型自动兼容setter的两种调用方式:直接传入新状态值、传入接收旧状态返回新值的更新函数
- 泛型
对应示例代码,正确写法如下:
// 从react导入对应的类型,推荐用import type避免类型代码被打包 import type { Dispatch, SetStateAction } from 'react'; const [infoText, setInfoText] = useState<string>(""); getInfoText(setInfoText); // 函数参数标注 export function getInfoText(setInfoText: Dispatch<SetStateAction<string>>) { // 内部可以正常调用,两种更新方式都有完整类型提示 setInfoText("新的文本内容"); setInfoText(prevText => prevText + "追加的后缀"); }
这个是无业务依赖的通用结论,不管useState初始化的是什么类型的状态,只需要把泛型T替换成对应状态的类型即可,比如数字类型状态对应Dispatch<SetStateAction<number>>、自定义接口类型状态对应Dispatch<SetStateAction<自定义接口名>>,没有额外适配成本。
简便推导写法
如果不想记忆内置类型名,可以直接借助TypeScript的typeof关键字从已有的setter变量上提取类型,效果和官方写法完全一致:
const [infoText, setInfoText] = useState<string>(""); // 直接提取setter的类型 type SetInfoText = typeof setInfoText; export function getInfoText(setInfoText: SetInfoText) { // 逻辑和类型提示和标准写法完全一致 }
常见错误写法
不要将setter类型简单标注为(value: T) => void,这种写法只支持直接传值的更新方式,丢失了函数式更新的类型支持,当你在函数内用setState(prev => ...)写法时,TypeScript会直接抛出类型错误。
内容的提问来源于stack exchange,提问作者Flip
相关产品推荐
相关产品推荐

