在React中使用TypeScript
1. 创建react应用
create-react-app 默认支持TS 添加template typescript 就行
npx create-react-app react-ts-basic --template typescript
2. 关键文件
1. react-app-env.d.ts :React项目默认的类型声明文件
三斜线指令 : 指定依赖的其他类型声明文件,types的值 表示依赖的类型声明文件包的名称
相当于其他引入类型声明文件
/// <reference types="react-scripts" />
// 声明加载资源
declare module '*.module.sass' {
const classes: {readonly [key:string]:string};
export default classes
}
// 声明加载资源
declare module '*.jpg' {
const src:string;
export default src
}
- TS会自动加载.d.ts 文件,以提供类型声明在
tsconfig.json文件中
{
// 表示在src文件夹里面所有的类型声明文件 会自动加载
"include": ['src']
}
2. tsconfig.json 指定TS的编译选项(比如,编译时是否移除注释)
{
"complerOptions": {
// 指定生成代码的语言版本
"target": "es5",
// 指定要包含在编译中的library
"lib": [
"dom", // 比如dom 表示dom所有的类型都提供了
"dom.iterable",
"esnext"
],
// 允许ts编译器编译js文件
"allowJs": true,
// 跳过声明文件的类型检查
"skipLibCheck": true,
// es模块 互操作 ,屏蔽ESModule 和 CommonJS 之间的差异
"esModuleInterop": true, // 库用的是CommonJS 但是也可以用ESModule导入
// 允许通过 import x from 'y' 即使模块没有显式指定 default
"allowSyntheticDefaultImports": true,
// 严格模式
"strict": true,
// 对文件名强制区分大小写
"forceConsistentCasingInFileNames": true,
// 为switch 语句启用错误报告
"noFallthroughCasesInSwitch": true,
// 生成代码的模块化标准
"module": "esnext", // 最新的es模块化标准
// 模块解析(查找)策略
"moduleResolution": "node", // 找一个文件按照node方式查找
// 允许导入扩展名为.json的模块
"resolveJsonModule": true,
// 是否将没有 import/export 的文件视为旧(全局而非模块化)脚本文件
"isolatedModules": true,
// 不生成JS文件(只进行类型检查)
"noEmit": true,
// 指定 jsx 编译成什么形式
"jsx": "react-jsx"
}
// 指定允许 ts 处理的目录
"include": ['src']
}
3. React 中常用的类型
- React项目是通过@types/react、@types/react-dom 类型声明包,来提供类型
- 参考资料 React+TS备忘单
- github.com/Microsoft/T…
1. 函数组件的类型以及组件的属性
import ReactDOM from "react-dom"
import { FC } from 'react'
/**
函数组件
*/
type Props = {name:string,age?:number}
// 正常
const Hello: FC<Props> = ({name,age}) => (
<div>您好,我叫:{name},我{age}岁了</div>
)
Hello.defaultProps = {
age:18
}
// 简化
const Hello = ({name,age = 18}: Props) => (
<div>您好,我叫:{name},我{age}岁了</div>
)
const App = () => <div>
<Hello name ='jirongliang' />
</div>
ReactDOM.render(<App />,document.getElementById('root'))
2. 事件绑定和事件对象
import ReactDOM from "react-dom"
import { FC } from 'react'
const Hello = ({name,age = 18}: Props) => (
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
console.log('赞!',e.currentTarget);
}
const onChange = (e:React.ChangeEvent<HTMLInputElement>) =>{
console.log(e.target.value);
}
<div>您好,我叫:{name},我{age}岁了</div>
<button onClick={onClick}>电子</button>
<input onChange={onChange}></input>
)
const App = () => <div>
<Hello name ='jirongliang' />
</div>
ReactDOM.render(<App />,document.getElementById('root'))
3. class组件类型
import ReactDOM from "react-dom"
import React from 'react'
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
// 为setState指定的类型
class Hello extends React.Component<Props,State>{
// 重新指定一次
state:State = {
count: 0
}
onIncrement = ()=>{
this.setState({
count: this.state.count + 1
})
}
}
const App = () => <div>
<Hello message ='jirongliang' />
<button onClick={this.onIncrement}>+1</button>
</div>
ReactDOM.render(<App />,document.getElementById('root'))