建议安装 @types/react 以及 ## @types/react-dom为devdependency
React内置类型
节点类型
如果你有一个组件接受另外一个组件作为chilren,那你应该如何给这个children声明类型呢?
React里有众多节点类型: JSX.Element,React.ReactChildren,React.ReactChild[],React.ReactNode
答案: 使用ReactNode。
JSX.Element 和 React.ReactNode
JSX.Element是React.createElement所返回的数据类型并且总是会是一个对象,而React.ReactNode则涵盖了一个组件所有可能的返回值。同理ReactChild。
CSS类型
React.CSSProperties 涵盖所有style类型
事件类型
表单事件 React.FormEventHandle
一个inputdom的 onChange回调可以这么写:
React.FormEventHandler<HTMLInputElement>
Contextual Type
也可以借助ts强大的 Contextual Type:
观察一下上面两段函数,区别就在于第二个button绑定的回调被当成一个独立函数拆了出来,结果就报了隐式any的类型错误,原因就是ts的 Contextual Type,第一个button所绑定的函数可以获得onClick所在“context”的类型推断!
常用dom事件类型
以下均可以使用 React[eventType] 方式获取。
- ChangeEvent 当 元素值value发生法改变时触发的事件类型
- ClipboardEvent 剪切板事件
- DragEvent 拖拽
- PointerEvent 一般触摸屏设备上多点触控事件
- WheelEvent 滚轮事件
- SyntheticEvent 合成事件 这个事件类型将涵盖所有react的事件类型因此当你不确定时可以使用这个类型
dom ref
ref非常灵活(既可以存放dom对象也可以存档mutable object)当我们在用ts的情况下使用useRef或者createRef时,往往会遇到各种类型问题。
存放dom时的典型例子
页面上有一个input在页面渲染完成后自动获得焦点。
import React,{ useEffect} from 'react'
function App() {
const inputEl = React.useRef(null)
useEffect(()=>{
inputEl.current.focus()
},[])
return (
<div className="App">
<input ref={inputEl}/>
</div>
)
}
export default App
这段代码在ts下会有两个类型问题:
1.current 对象可能会为null
解决方法:
// !非空断言
const inputEl = React.useRef(null!)
// ? optional chain
useEffect(()=>{
inputEl.current?.focus()
},[])
但是仅仅这样还不够因为此时useRef并不知道自己接受到的是什么,它会默认把它当成never来处理
会提示:
此时需要依靠泛型来收束我们想要的类型:
// 指定 HTMLInputElement 类型
const inputEl = React.useRef<HTMLInputElement>(null!)
dom类型那么多,我找不到具体名称是哪个怎么办?
写一个错误的html类型,比如一律写成HTMLDivElement 然后编辑器会给你正确的类型提示:
如此一来就能充分享受类型红利。