创建ts类型的react项目
npx create-react-app my-app --template typescript
创建完成之后会生成一个tsconfig.json文件,项目文件可以创建对应的ts和tsx文件, .d.ts 类型声明文件,用来指定类型。
tsconfig.json基本配置
tsconfig.json是typescript项目的配置文件,用于配置typescript:
{
// 编译选项
"compilerOptions": {
// 生成代码的语言版本:将我们写的 TS 代码编译成哪个版本的 JS 代码
// 命令行: tsc --target es5 11-测试TS配置文件.ts
"target": "es5",
// 指定要包含在编译中的 library
"lib": ["dom", "dom.iterable", "esnext"],
// 允许 ts 编译器编译 js 文件
"allowJs": true,
// 跳过类型声明文件的类型检查
"skipLibCheck": true,
// es 模块 互操作,屏蔽 ESModule 和 CommonJS 之间的差异
"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"]
}
基本类型
//基本类型
let name:string = "123";
//数组类型
let arr:number[] = [1,2,3];
let arr2:(number|string)[] = ['1',2,3];
let arr3:Array<number|string> = ['1',2,3];
//对象类型
interface Itype{
name:string,
age?:number,
[propName:string]:any
}
const obj:Itype = {
name: '123',
sex:'女‘
}
//函数类型
function testFun(a:string,b?:number){
return a.substring(0,1);
}
testFun("1",2);
interface IFun{
getName:()=>string;
}
//类
class Test implements IFun {
//限定符使用
private a:string;
getName(){
return "123";
}
}
类组件
import React from 'react';
interface IState{
name:string;
}
interface IProp{
age:number;
}
class App extends React.Component<IProp,IState>{
state = {
name:"123"
}
render(){
return <div>
{this.props.age}
<button onClick={()=>{
this.setState({
name:"123"
})}
}></button>
</div>
}
}
export default App;
类组件可以在泛型中约定props以及state的类型,如上使用IProp约props,IState约束state.
函数组件
函数组件中props类型定义
//1.使用接口
import React from 'react';
interface Itype{
name:string,
setName:(name:string)=>void
}
function App(props:Itype){
return (<div>
{props.name}
<button onClick={()=>{
props.setName("123")
}}></button>
</div>)
}
export default App;
//2,使用泛型
const App:React.FC<Itype> = (props)=>{
const [age,setAge] = useState<number>();
const myref = useRef<HTMLButtonElement>(null)
return (<div>
{props.name}
<button ref = {myref} onClick={()=>{
props.setName("123")
}}></button>
</div>)
}
函数组件中state类型定义
const [age,setAge] = useState<number>();
函数组件中ref类型定义
const myref = useRef<HTMLButtonElement>(null)
路由
如果要使用路由库的路由类型,必须安装对应的类型文件,在react中使用react-router-dom需要安装@types/react-router-dom类型定义文件。但是有些库会自带类型定义,例如'axios',自动导入该库时会自动加载它的类型声明文件。
这里展示的是react-router-domv5版本的路由参数类型定义:
import {HashRouter,Route,RouteComponentProps} from 'react-router-dom'
interface Itype{
name:string,
setName:(name:string)=>void
}
function App(props:RouteComponentProps<Itype>){
return (<div>
{props.name}
<button onClick = {
() => {console.log(props.history)}}>
获取history对象
</button>
</div>)
}
function Film(){
return <div>Film</div>
}
function Center(){
return <div>center</div>
}
RouteComponentProps<Itype>可以定义路由参数类型,这样就可以从props对象拿到路由中的history等属性,同时拿到父组件传入的参数。
redux
import { createStore } from "redux"
interface IAction {
type: string,
payload?: any
}
interface IState {
isShow: boolean
}
const reducer = (prevState:IState={
isShow: true
},
action: IAction) => {
const {type} = action
const newState = {...prevState}
switch(type) {
case "show":
newState.isShow = true
return newState
case "hide":
newState.isShow = false
return newState
default:
return prevState
}
}
const store = createStore(reducer)
export default store
redux中我们定义了两个接口去限制了state和action的类型推断,让我们在写代码的阶段就能够将写错字母的问题给提前发现.