快速掌握在react项目中使用Typescript——配置文件及组件

微生令
2023-12-01

一、TS配置文件tsconfig.json

一般在react中使用typescript,会生成一个tsconfig.json文件指定项目文件和项目编译所需的配置项,接下来介绍一下该文件的配置项具有什么含义。
注意:TS配置项非常多(100+),以CRA项目中的配置为例,其他的配置项用到的时候查阅文档即可;

  1. tsconfig.json文件所在目录为项目根目录(与package.json同级)
  2. tsconfig.json可以自动生成,命令:tsc--init

以下就是我在做项目的过程中生成的react项目中的tsconfig.json配置项,下面将以这个文件的内容为基础进行说明(具体说明写在注释里):

    {
        //编译选项
      "compilerOptions": {
        //生成代码的语言版本
        "target": "es5",
        //指定要包含在编译中的library
        "lib": [
          "dom",
          "dom.iterable",
          "esnext"
        ],
        //允许ts编译js文件
        "allowJs": true,
        //跳过声明文件的类型检查
        "skipLibCheck": true,
        //es模块,互操作,屏蔽es模块化和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"
      ]
    }

二、在React中使用Typescript

React是组件化开发模式,React开发任务就是写组件,现存主要有两种组件,一个是函数组件,一个是class组件。

函数组件

  1. 函数组件的类型以及组件的属性
    import {FC} from 'react'
    type Props={name:string;age?:number};//这里的?表示age属性可选
    //第一种写法
    const Hello:FC<Props>=({name,age})=>(
        <div>你好,我叫:{name},我{age}岁了</div>
    )
    //第二种写法
    // const Hello=({name,age}:Props)=>(
    //     <div>你好,我叫:{name},我{age}岁了</div>
    // )
    ---------------------------------
    //调用Hello组件
    <Hello name="jack"/>

这个FC就是React中提供的一个类型,FCfunctioncomponent的简写,且FC是一个泛型,所以能传入一个类型变量,如果这里不能理解的话(这里其实我当时思考了很久),可以把数组类型做类比,比如:

    let nums=new Array<string>();
    nums.push('Hello');

这里的FC就相当于Array,props就是string
2. 函数组件属性的默认值
下面代码中,我们使用defaultProps中指定了属性的默认值

    import {FC} from 'react'
    type Props={name:string;age?:number};//这里的?表示age属性可选
    //第一种写法
    const Hello:FC<Props>=({name,age})=>(
        <div>你好,我叫:{name},我{age}岁了</div>
    )
    Hello:defaultProps={
        age:18
    }
    ---------------------------------
    //调用Hello组件
    <Hello name="jack"/>

实际上,还有一种简化的写法:

    const Hello=({name,age=18}:Props)=>(
        <div>你好,我叫:{name},我{age}岁了</div>
    )
  1. 事件绑定和事件对象
    假设有一个按钮,我们点击这个按钮跳转事件,首先进行事件绑定:
    <button onClick={onClick}>点赞</button>
    //如果事件处理程序中没有参数,就和js中一样
    const onClick=()=>{}
    //如果事件处理程序中有参数:
    const onClick=(e:React.MouseEvent<HTMLButtonElement>)=>{
      console.log(e.currentTarget);
    }

除此之外,还有文本框:

    <input onChange={onChange}>点赞</input>
    //如果事件处理程序中没有参数,就和js中一样
    const onChange=()=>{}
    //如果事件处理程序中有参数:
    const onChange=(e:React.ChangeEvent<HTMLInputElement>)=>{
      console.log(e.target.value)
    }

如果我们不太确定事件处理程序是类型,这里有个小技巧:在jsx中写事件处理程序(e=>{}),然后把鼠标放在e上,利用TS的类型推论来查看事件对象的类型

类组件

  1. class组件的类型
    这里需要注意和函数hooks的区别在于,class组件需要传入两个参数:
      type State={count:number};
      type Props={message?:string}
      //class的写法也有四种,分别为:
      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
  1. class组件的属性和属性默认值
      type Props={name:string;age?:number};
      class Hello extends React.Component<Props>{
        static defaultProps:Partial<Props>={
          age:18;
        }
        render(){
          const {name,age}=this.props;
          return <div>你好,我叫:{name},我{age}岁了</div>
        }
      }
  1. class组件的组件状态和事件
      type State={count:number};
      class Hello extends React.Component<{},<State>>{
        state:State={
          count:0;
        }
        onIncrement=()=>{
          this.setState({
            count:this.state.count+1;
          })
        }
        render(){
          return (<div>
            <button onClick={this.onIncrement}>+1</button>
          </div>)
        }
      }
 类似资料: