博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在React项目中优雅地使用Typescript
阅读量:4083 次
发布时间:2019-05-25

本文共 4033 字,大约阅读时间需要 13 分钟。

「优雅」的含义:

  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,因为:

const defaultProps = {  who: "Johny Five"};type IProps = { age: number } & typeof defaultProps;export const Greet = (props: IProps) => { return 
123
};Greet.defaultProps = defaultProps;

事实上,,所以以后还是尽量减少在函数组件上使用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<IProps, IState>有重复的嫌疑,但是这两者实际上是不同的:

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

可渲染节点类型

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

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

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<Props>(即 React.FunctionComponent<Props>
  • React.Component<Props, State>
  • React.ComponentType<Props>(即ComponentClass<P> | FunctionComponent<P>

    在写HOC的时候经常用到。

    const withState = 

    ( WrappedComponent: React.ComponentType

    ,) => { ...

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

比如,以下例子获取并扩展了<button>的props类型:

export const PrimaryButton = (  props: Props & React.HTMLProps
) =>
;

PrimaryButton能够接受所有原生<button>所接受的props。关键在于React.HTMLProps

获取并扩展第三方组件的props类型

import { Button } from "library"; // but doesn't export ButtonProps! oh no!type ButtonProps = React.ComponentProps
; // no problem! grab your own!type AlertButtonProps = Omit
; // modifyconst AlertButton: React.FC
= props => (

事件类型

@types/react提供了各种事件的类型,比如以下是使用React.FormEvent的例子:

class App extends React.Component<  {},  {    text: string  }> {  state = {    text: '',  }  onChange = (e: React.FormEvent
): void => { this.setState({ text: e.currentTarget.value }) } render() { return (
) }}

在React中,所有事件(包括、、等)都是的子类型。他们在@types/react中定义如下:

// DOM事件的基本属性都定义在这里interface BaseSyntheticEvent
{ nativeEvent: E; currentTarget: C; target: T; bubbles: boolean; cancelable: boolean; defaultPrevented: boolean; eventPhase: number; isTrusted: boolean; preventDefault(): void; isDefaultPrevented(): boolean; stopPropagation(): void; isPropagationStopped(): boolean; persist(): void; timeStamp: number; type: string;}interface SyntheticEvent
extends BaseSyntheticEvent
{}// 具体的事件类型:interface FormEvent
extends SyntheticEvent
{}interface KeyboardEvent
extends SyntheticEvent
{ altKey: boolean; // ...}interface MouseEvent
extends SyntheticEvent
{ altKey: boolean; // ...}// ...

参考资料

转载地址:http://hiqni.baihongyu.com/

你可能感兴趣的文章
read humor_campus
查看>>
IBM WebSphere Commerce Analyzer
查看>>
my read work
查看>>
db db2 base / instance database tablespace container
查看>>
hd disk / disk raid / disk io / iops / iostat / iowait / iotop / iometer
查看>>
project ASP.NET
查看>>
db db2_monitorTool IBM Rational Performace Tester
查看>>
OS + Unix Aix telnet
查看>>
IBM Lotus
查看>>
Linux +Win LAMPP Tools XAMPP 1.7.3 / 5.6.3
查看>>
my read_university
查看>>
network manager
查看>>
OS + Linux Disk disk lvm / disk partition / disk mount / disk io
查看>>
RedHat + OS CPU、MEM、DISK
查看>>
net TCP/IP / TIME_WAIT / tcpip / iperf / cain
查看>>
webServer kzserver/1.0.0
查看>>
OS + Unix IBM Aix basic / topas / nmon / filemon / vmstat / iostat / sysstat/sar
查看>>
my ReadMap subway / metro / map / ditie / gaotie / traffic / jiaotong
查看>>
OS + Linux DNS Server Bind
查看>>
linux下安装django
查看>>