TypeScript在React中的使用
在 React中使用TypeScript
概述
现在,我们已经掌握了TS 中基础类型、高级类型的使用了。但是,如果要在前端项目开发中使用TS,还需要掌握React、Vue、Angular等这些库或框架中提供的 API的类型,以及在TS中是如何使用的。接下来,我们以React为例,来学习如何在React项目中使用TS。包括以下内容:
使用 CRA 创建支持 TS 的项目
React脚手架工具create-react-app(简称:CRA)默认支持TypeScript。
创建支持TS 的项目命令:npx create-react-app 项目名称 --template typescript。
国外的源比较慢,改成淘宝的:
npm config set registry https://registry.npmmirror.com
如果使用react19版本会报错,使用命令:
yarn create react-app my-app --template typescript
当看到以下提示时,表示支持TS的项目创建成功:
We suggest that you begin by typing:
cd react-ts-basic
yarn start
Happy hacking!
更多:在已有项目中使用TS
相对于非 TS 项目,目录结构主要由以下三个变化:
-
项目根目录中增加了 tsconfig.json 配置文件:指定TS的编译选项(比如,编译时是否移除注释)。
-
React 组件的文件扩展名变为:*.tsx。
-
src 目录中增加了react-app-env.d.ts:React项目默认的类型声明文件。
react-app-env.d.ts: React项目默认的类型声明文件。
三斜线指令:指定依赖的其他类型声明文件,types表示依赖的类型声明文件包的名称。
/// <reference types="react-scripts" />
解释:告诉TS 帮我加载react-scripts 这个包提供的类型声明。
react-scripts 的类型声明文件包含了两部分类型:
-
react、react-dom、node 的类型
-
图片、样式等模块的类型,以允许在代码中导入图片、SVG等文件。
TS 会自动加载该 .d.ts 文件,以提供类型声明(通过修改tsconfig.json 中的include 配置来验证)。
TS 配置文件 tsconfig.json
tsconfig.json 指定:项目文件和项目编译所需的配置项,
注意:TS的配置项非常多(100+),以CRA项目中的配置为例来学习,其他的配置项用到时查文档即可
- tsconfig.json 文件所在目录为项目根目录(与package.json 同级)。
- tsconfig.json 可以自动生成,命令:tsc --init。
//ts文件说明
{
// 编译选项
"compilerOptions": {
// 生成代码的语言版本
"target": "es5",
// 指定要包含在编译中的 library
"lib": [
"dom",
"dom.iterable",
"esnext"
],
// 允许 ts 编译器编译 js 文件
"allowJs": true,
// 跳过声明文件的类型检查
"skipLibCheck": true,
// es 模块互操作,屏蔽ESModule 和Common]s 之间的差异
"esModuleInterop": true,
// 允许通过import x from'y' 即使模块没有显式指定 default 导出
"allowSyntheticDefaultImports": true,
// 开启严格模式
"strict": true,
// 对文件名称强制区分大小写
"forceConsistentCasingInFileNames": true,
// 为 switch 语句启用错误报告
"noFallthroughCasesInSwitch": true,
// 生成代码的模块化标准
"module": "esnext",
// 模块解析(查找)策略
"moduleResolution": "node",
// 允许导入扩展名为.json的模块
"resolveJsonModule": true,
// 是否将没有 import/export 的文件视为旧(全局而非模块化)脚本文件。
"isolatedModules": true,
// 编译时不生成任何文件(只进行类型检查)
"noEmit": true,
// 指定将 JSX 编译成什么形式
"jsx": "react-jsx"
},
// 指定允许ts处理的目录
"include": [
"src"
]
}
除了在 tsconfig.json 文件中使用编译配置外,还可以通过命令行来使用。
使用演示:tsc hello.ts --target es6。
注意:
-
tsc后带有输入文件时(比如,tschello.ts),将忽略tsconfig.json 文件。
tsc hello.ts -
tsc后不带输入文件时(比如,tsc),才会启用tsconfig.json。
tsc
推荐使用: tsconfig.json配置文件
前提说明: 现在,基于class 组件来讲解React+TS 的使用
在不使用TS 时,可以使用 prop-types 库,为 React 组件提供类型检查
说明: TS项目中,推荐使用TypeScript实现组件类型校验(代替PropTypes)。
不管是 React 还是 Vue,只要是支持TS 的库,都提供了很多类型,来满足该库对类型的需求。
注意:
-
React 项目是通过 @types/react、@types/react-dom 类型声明包,来提供类型的。
-
这些包 CRA已帮我们安装好(react-app-env.d.ts),直接用即可。
参考资料: React文档-静态类型检查、React+TS备忘单
React 中的常用类型
React是组件化开发模式,React开发主要任务就是写组件,两种组件:1函数组件 2class组件。
- 函数组件,主要包括以下内容:
-
组件的类型和组件的属性(props)
type Props = {name:string,age?:number} const Hello:FC<Props> = ({name,age}) => ( <div>你好,我叫:{name},我 {age} 岁</div> ) const App = () => ( <div> <Hello name="jack" age={1}></Hello> </div> )函数组件的类型以及组件的属性实际上,还可以直接简化为(完全按照函数在TS中的写法):
const Hello = ({name,age}:Props) => ( <div>你好,我叫:{name},我 {age} 岁</div> ) -
组件属性的默认值(defaultProps)
const Hello = ({name,age=18}:Props) => ( <div>你好,我叫:{name},我 {age} 岁</div> ) -
事件绑定和事件对象
const Hello = ({name,age=18}:Props) => { const onClick = (e: React.MouseEvent<HTMLButtonElement>)=>{ console.log("赞",e.currentTarget) } const onChange = (e:React.MouseEvent<HTMLInputElement>)=>{ console.log(e.currentTarget.value) } return ( <div> 你好,我叫:{name},我 {age} 岁 <button onClick={onClick}>点赞</button> <input onClick={onChange}/> </div> ) }技巧:在JSX中写事件处理程序(e=>{}),然后,把鼠标放在e上,利用TS的类型推论来查看事件对象类型。
<input onClick={e=>{}}/> //e => e: React.MouseEvent<HTMLInputElement>
- class 组件,主要包括以下内容:
-
组件的类型、属性、事件
type State = {count:number} type Props = {message?: string} class C1 extends React.Component {} //无 props、state class C2 extends React.Component<Props> {} //有props,无 state class C3 extends React.Component<{},State>{} //无props,有state class C4 extends React.Component<Props,State>{} //有props、state //类属性的使用及默认值的添加方式 Props的方式 class HelloProps extends React.Component<Props> { // static defaultProps:Partial<Props> = { // age:27 // } render() { const {name,age = 80} = this.props; return <div>你好,我叫:{name},我 {age} 岁</div>; } } -
组件状态(state)
class Counter extends React.Component<{}, State> { state: State = { count: 0 } inscream = () => { this.setState({ count: this.state.count + 1 }) } render() { return <div> 计数器:{this.state.count} <button onClick={this.inscream}>+1</button> </div>; } }

浙公网安备 33010602011771号