在React项目中优雅地使用Typescript

「优雅」的含义:

  1. 减少编写冗余的类型定义、类型标注,充分利用ts的自动类型推断,以及外部提供的类型声明。
  2. 类型安全:提供足够的类型信息来避免运行时错误,让错误暴露在开发期。这些类型信息同时能够提供代码补全、跳转到定义等功能。

组件定义

函数组件

import * as React from 'react';
// 如果在tsconfig中设置了"allowSyntheticDefaultImports": true
// 你还可以更精练地import react:
// import React from "react";

interface IProps {
      // CSSProperties提供样式声明的类型信息
      // 用户传入style的时候就能够获得类型检查和代码补全
      style?: React.CSSProperties;
      // 使用@types/react提供的事件类型定义,这里指定event.target的类型是HTMLButtonElement
      onClick(event: React.MouseEvent): void;
    // ...
}
const MyComponent: React.FC = (props) => {
      const { children, ...restProps } = props;
    return 
{children}
; }
  1. FC是FunctionComponent的缩写。
  2. IProps无需声明children属性的类型。React.FC会自动为props添加这个属性类型。

    当然,如果children期望一个render prop,或者期望其他特殊的值,那么你还是要自己给 children声明类型,而不是使用默认的 React.ReactNode
  3. props无需做类型标注。

函数组件defaultProps(Deprecate)

如果你需要定义defaultProps,那么不要使用React.FC,因为React.FC对defaultProps的支持不是很好:

const defaultProps = {
  who: "Johny Five"
};
type IProps = { age: number } & typeof defaultProps;

export const Greet = (props: IProps) => { return 
123
}; Greet.defaultProps = defaultProps;

事实上,一个提议在函数组件中废弃defaultProps的React rfc已经被接受,所以以后还是尽量减少在函数组件上使用defaultProps,使用ES6原生的参数解构+默认参数特性就已经能够满足需要:

const TestFunction: FunctionComponent = ({ foo = "bar" }) => 
{foo}

类组件

interface IProps {
  message: string;
}
interface IState {
  count: number;
}
export class MyComponent extends React.Component {
  state: IState = {
    // duplicate IState annotation for better type inference
    count: 0
  };
  render() {
    return (
      
{this.props.message} {this.state.count}
); } }
  1. 如果你通过声明state属性来初始化state,那么你需要为这个属性增加IState类型标注。虽然这与前面的React.Component有重复的嫌疑,但是这两者实际上是不同的:

    • React.Component只是标注了基类的state属性类型。
    • 而当你在子类声明state时,你可以为state标注一个【IState的子类型】作为override。这样,this.state会以子类中的state属性声明作为类型信息的来源。
  2. 建议使用函数组件。

可渲染节点类型

可渲染节点就是:可以直接被组件渲染函数返回的值。

与可渲染节点有关的类型定义如下(摘录自@types/react):

type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
interface ReactNodeArray extends Array {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

组件类型

  • React.FC(即 React.FunctionComponent
  • React.Component
  • React.ComponentType(即ComponentClass

    | FunctionComponent


    在写HOC的时候经常用到。

    const withState = 

    ( WrappedComponent: React.ComponentType

    , ) => { ...

获取并扩展原生元素的props类型

比如,以下例子获取并扩展了

你可能感兴趣的:(【React.js点滴知识,】)