TypeScript useState 类型怎么用

很多刚接触 TypeScript 的 React 开发者,都会在 useState 上犯愁:明明 JavaScript 里写 useState 没什么问题,加了类型之后,怎么就总报错、还不知道怎么给变量“定规矩”?其实 useState 的类型用法远没那么复杂,用几个生活化的例子就能讲明白。

不用特意写类型的情况:自动“猜”类型

如果你给 useState 传了初始值,TypeScript 会自动根据初始值“猜”出状态的类型,不用额外写代码。比如你写 const [name, setName] = useState('张三'),TypeScript 一眼就能看出来 name 只能是字符串,以后给 setName 传数字的话,直接就会标红报错。

TypeScript useState 类型怎么用

再举个生活化的例子:你把一个带“姓名”的便利贴贴在冰箱上,别人看到就知道这张纸上只能写名字,写数字或地址就不对。这里的初始值 '张三' 就是那张便利贴,TypeScript 会自动把“便利贴的内容只能是姓名类的字符”记下来,不用你额外说规则。

初始值是空的情况:主动“告诉”类型

如果初始值是空的,比如空字符串 ''、空数组 [],TypeScript 就猜不准类型了。比如 const [hobby, setHobby] = useState(''),你写了个空字符串,它会以为 hobby 只能是字符串,以后想存一个数字爱好比如 setHobby(123),就会报错;如果写 const [list, setList] = useState([]),它会以为 list 是 never[]——就是啥类型都不能存的数组,想放个字符串或对象也会报错。

这时候就需要手动给 useState 加类型注解,相当于提前给空便利贴标好“只能写水果名字”,而不是随便写。用法就是在 useState 后面加 <>,尖括号里写你要的类型:比如要存字符串就写 useState<string>(''),要存数字就写 useState<number>(0),要存对象就先定义个类型再写。

存对象/数组的情况:提前“定好具体格式”

如果状态是对象或数组,类型注解还能帮你定好具体格式,避免乱填。比如要存一个用户信息,里面有姓名(字符串)、年龄(数字),你可以先定义个类型,再传给 useState:

`typescript

type User = { name: string; age: number };

const [user, setUser] = useState<User>({ name: '李四', age: 20 });

`

这就像你提前画了个“用户信息表格”,规定好每一格要写什么,以后想给 user 加个 email 字段,或者把 age 写成字符串,TypeScript 都会直接报错。

如果要存数组,比如存多个水果,就写 useState<string[]>([]),意思是“数组里每一项都是字符串”;如果要存对象数组,就写 useState<User[]>([]),和上面的例子同理,规定数组里的每个元素都是符合 User 格式的对象。

常见小坑:别和原始 JS 用法混

有个很多人踩的坑:明明写了类型注解,还是报错。比如写 const [count, setCount] = useState<number>(0),结果写 setCount('5'),直接把字符串传给数字类型,肯定报错,这和 JavaScript 里传错类型报错是一个道理,只是 TypeScript 提前帮你拦住了。

还有一个坑:如果初始值是 null,比如 useState<User | null>(null),意思是“状态要么是 User 对象,要么是 null”,这时候用 user 的时候,要先判断不是 null,不然会报错,就像你拿到那张标了“用户信息”的便利贴,看到是空的时候,不能直接读名字,得先确认上面有内容。

其实 TypeScript useState 的核心,就是给状态定好“能存什么”的规则,自动猜的情况不用多写,拿不准的就手动标类型,存复杂数据的就定好具体格式,只要顺着这个逻辑用,就不会再懵了。

上一篇 C / C++ 编程语言的核心特性与入门实践技巧科普