react中使用ts

257 阅读3分钟

创建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中我们定义了两个接口去限制了stateaction的类型推断,让我们在写代码的阶段就能够将写错字母的问题给提前发现.