把TypeScript和React放一块儿,那感觉就像是给一辆好车装上了精准的导航和一大堆传感器。刚开始可能觉得手脚有点束缚,开熟了之后,你就再也回不去了——那种在编码时就能提前发现各种低级错误的安全感,是真让人上瘾。
![图片[1]-如何在React项目中使用TypeScript?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/351f0f2ced6949eabd0ce9f50a806414_tplv-tb4s082cfz-aigc_resize_1080_1080-1024x683.webp)
咱们从最基础的组件说起。用TS写函数组件,核心就是定义Props的类型。别再用PropTypes了,那东西运行时才检查,TS在编译时就能帮你搞定。
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
}
const MyButton: React.FC<ButtonProps> = ({ label, onClick, disabled }) => {
return <button onClick={onClick} disabled={disabled}>{label}</button>;
};
用React.FC这个泛型类型来声明组件,它能自动包含children属性,而且对返回值的类型检查更严格。当然,也有人不喜欢React.FC,觉得它隐式包含children有时反而是麻烦。那直接用普通函数声明也行,就是记得标明返回值是JSX.Element或者React.ReactElement。
处理组件内部状态,useState的类型推断通常很聪明。你给个初始值,它就知道类型了。
const [count, setCount] = useState(0); // count 自动就是 number
但如果状态初始可能是null,你就得显式告诉它泛型参数了:
const [user, setUser] = useState<User | null>(null);
用useRef的时候也得留神。如果拿来存DOM节点,类型要写对:
const inputRef = useRef<HTMLInputElement>(null);
如果是存一个可变的值,不与DOM关联,那记得在泛型参数里把null排除掉,并给current一个初始值:
const timerRef = useRef<number | undefined>(undefined);
事件处理是另一个高频场景。别再把事件类型写成any了,React已经为我们提供了完备的类型。
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value);
};
像ChangeEvent、MouseEvent这些,都是泛型类型,需要你指定具体的DOM元素类型。多写几次就记住了,实在想不起来,就在事件处理函数里先写个e:,让编辑器的自动提示来帮你。
和外部数据打交道时,比如从API拿到一组用户数据,为它定义一个接口,然后用useState初始化,这样整个数据流里类型都是清晰的。
interface User {
id: number;
name: string;
}
const [users, setUsers] = useState<User[]>([]);
新手最容易懵的地方大概是Hooks的依赖数组。记住,只要依赖项里用到了某个变量或函数,而它不是在组件内部定义的,你就可能需要手动处理它的类型。自定义Hook的返回值最好也用元组类型明确标出来。
用着用着你可能会发现,有些第三方React库没有提供类型。先去试试安装@types/包名。如果找不到,就在项目里创建一个declarations.d.ts文件,用declare module给它一个临时类型,或者勇敢点,自己为它写一份完整的类型声明。
总的来说,在React里用TS,就是一个让组件契约从模糊变清晰的过程。前期多花几分钟定义类型,后期能省下大量调试和沟通的时间。就从给下一个组件的Props写一个清晰的interface开始吧。


























暂无评论内容