文章

React typescript cheatsheet

React typescript cheatsheet

React Typescript Cheetsheet

JSX.Element vs React.ReactNode

  • jsx.element -> React.createElement 的返回值
  • React.ReactNode -> 组件返回值的集合

interface or type?

使用 Interface 直到你需要 Type

  • 在编写库或第 3 方环境类型定义时,始终 interface 用于公共 API 的定义,因为这允许消费者在缺少某些定义时通过声明合并来扩展它们。
  • 在你的 React 组件 Props 和 State 使用 Type,以保持一致性并且因为它受到更多限制。

custom hooks

1
2
3
4
5
6
7
8
9
10
import { useState } from "react";

export function useLoading() {
  const [isLoading, setState] = useState(false);
  const load = (aPromise: Promise<any>) => {
    setState(true);
    return aPromise.finally(() => setState(false));
  };
  return [isLoading, load] as const; // infers [boolean, typeof load] instead of (boolean | typeof load)[]
}

当你解构时,你会在解构的位置获取正确的类型
或者编写一个自动类型推断的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 这个函数仅仅为了让TS自动推断参数类型
function tuplify<T extends any[]>(...elements: T) {
  return elements;
}

function useArray() {
  const numberValue = useRef(3).current;
  const functionValue = useRef(() => {}).current;
  return [numberValue, functionValue]; // type is (number | (() => void))[]
}

function useTuple() {
  const numberValue = useRef(3).current;
  const functionValue = useRef(() => {}).current;
  return tuplify(numberValue, functionValue); // type is [number, () => void]
}

class Component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type MyProps = {
  // using `interface` is also ok
  message: string,
};
type MyState = {
  count: number, // like this
};
class App extends React.Component<MyProps, MyState> {
  state: MyState = {
    // optional second annotation for better type inference
    count: 0,
  };
  render() {
    return (
      <div>
        {this.props.message} {this.state.count}
      </div>
    );
  }
}

为什么要注释两次 state?
对类属性进行注释不是必要的,但它允许在访问 this.state 和初始化状态时更好地进行类型推断。
注释以两种不同的方式工作,第二个泛型类型参数将允许 this.setState() 正常工作,因为该方法来自基类,但 state 在组件内部初始化时可能会覆盖基类的实现,因此您必须确保告诉编译器你实际上并没有做任何不同的事情。
不需要添加 readonly

1
2
3
4
5
6
type MyProps = {
  readonly message: string;
};
type MyState = {
  readonly count: number;
};

React.Component<P,S> 已经默认标记它们为不可变。

本文由作者按照 CC BY 4.0 进行授权