收集于:
https://zhuanlan.zhihu.com/p/39620591

巧用注释

通过/** */形式的注释可以给 TS 类型做标记,编辑器会有更好的提示:

  1. /** A cool guy. */
  2. interface Person {
  3. /** A cool name. */
  4. name: string,
  5. }

TypeScript使用技巧整理 - 图1
注释有很多规范的字段,在 /** */ 里输入 @ 就可以看到丰富的选择:

巧用typeof

我们一般先写类型,再使用:

  1. interface Opt {
  2. timeout: number
  3. }
  4. const defaultOption: Opt = {
  5. timeout: 500
  6. }

有时候可以反过来:

  1. const defaultOption = {
  2. timeout: 500
  3. }
  4. type Opt = typeof defaultOption

当一个 interface 总有一个字面量初始值时,可以考虑这种写法以减少重复代码。

巧用联合类型

Dinner 要么有 fish 要么有 bear

  1. // 🙁 Not good.
  2. interface Dinner1 {
  3. fish?: number,
  4. bear?: number,
  5. }
  6. // 🙂 Awesome!
  7. type Dinner2 = {
  8. fish: number,
  9. } | {
  10. bear: number,
  11. }

一些区别:

  1. let d1: Dinner1 = {} // Opps
  2. d1 = {fish:1, bear:1} // Opps
  3. let d2: Dinner2 = {} // Protected!
  4. d2 = {fish:1, bear:1} // Protected!
  5. if ('fish' in d2) {
  6. // `d2` has `fish` and no `bear` here.
  7. } else {
  8. // `d2` has `bear` and no `fish` here.
  9. }

巧用查找类型

  1. interface Person {
  2. addr: {
  3. city: string,
  4. street: string,
  5. num: number,
  6. }
  7. }

当需要使用 addr 的类型时,除了把类型提出来

  1. interface Address {
  2. city: string,
  3. street: string,
  4. num: number,
  5. }
  6. interface Person {
  7. addr: Address,
  8. }

巧用查找类型+泛型+keyof

  1. interface API {
  2. '/user': { name: string },
  3. '/menu': { foods: Food[] },
  4. }
  5. const get = <URL extends keyof API>(url: URL): Promise<API[URL]> => {
  6. return fetch(url).then(res => res.json())
  7. }

TypeScript使用技巧整理 - 图2
TypeScript使用技巧整理 - 图3

巧用显式泛型

$('button') 是个 DOM 元素选择器,可是返回值的类型是运行时才能确定的,除了返回 any,还可以

  1. function $<T extends HTMLElement>(id: string):T {
  2. return document.getElementById(id)
  3. }
  4. // Tell me what element it is.
  5. $<HTMLInputElement>('input').value

函数泛型不一定非得自动推导出类型,有时候显式指定类型就好。

巧用 DeepReadonly

  1. type DeepReadonly<T> = {
  2. readonly [P in keyof T]: DeepReadonly<T[P]>; // 递归
  3. }
  4. const a = { foo: { bar: 22 } }
  5. const b = a as DeepReadonly<typeof a>
  6. b.foo.bar = 33 // Hey, stop!

巧用 Omit

  1. import { Button, ButtonProps } from './components/button'
  2. type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
  3. type BigButtonProps = Omit<ButtonProps, 'size'>
  4. function BigButton(props: BigButtonProps) {
  5. return Button({ ...props, size: 'big' })
  6. }