This website requires JavaScript.
en
hb

Ts 进阶用法大全

初听不识曲中意,再听已是曲中人,正如这首诗一样初学 Ts 的时候不太理解高级用法,现在用多了感觉到这里面的重要性,所以整理一波经验值

交叉类型(&)

interface Button {
  type: string
  text: string
}

interface Link {
  alt: string
  href: string
}

const linkBtn: Button & Link = {
  type: 'danger',
  text: '跳转到百度',
  alt: '跳转到百度',
  href: 'http://www.baidu.com'
}

联合类型(|)

interface Button {
  type: 'default' | 'primary' | 'danger'
  text: string
}

const btn: Button = {
  type: 'primary',
  text: '按钮'
}

类型索引(keyof)

interface Button {
    type: string
    text: string
}

type ButtonKeys = keyof Button
// 等效于
type ButtonKeys = "type" | "text"

类型约束(extends)


type BaseType = string | number | boolean

// 这里表示 copy 的参数
// 只能是字符串、数字、布尔这几种基础类型
function copy<T extends BaseType>(arg: T): T {
  return arg
}

// 共用
function getValue<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}

const obj = { a: 1 }
const a = getValue(obj, 'a')

类型映射(in)

in 关键词的作用主要是做类型的映射,遍历已有接口的 key 或者是遍历联合类型。下面使用内置的泛型接口 Readonly 来举例。

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

interface Obj {
  a: string
  b: string
}

type ReadOnlyObj = Readonly<Obj>

条件类型(U ? X : Y)

条件类型的语法规则和三元表达式一致,经常用于一些类型不确定的情况。


// T extends U ? X : Y

type Extract<T, U> = T extends U ? T : never;


interface Worker {
  name: string
  age: number
  email: string
  salary: number
}

interface Student {
  name: string
  age: number
  email: string
  grade: number
}


type CommonKeys = Extract<keyof Worker, keyof Student>
// 'name' | 'age' | 'email'

工具泛型

Partial

Partial 用于将一个接口的所有属性设置为可选状态,首先通过 keyof T,取出类型变量 T 的所有属性,然后通过 in 进行遍历,最后在属性后加上一个 ?。 我们通过 TypeScript 写 React 的组件的时候,如果组件的属性都有默认值的存在,我们就可以通过 Partial 将属性值都变成可选值

type Partial<T> = {
    [P in keyof T]?: T[P]
}
import React from 'react'

interface ButtonProps {
  type: 'button' | 'submit' | 'reset'
  text: string
  disabled: boolean
  onClick: () => void
}

// 将按钮组件的 props 的属性都改为可选
const render = (props: Partial<ButtonProps> = {}) => {
  const baseProps = {
    disabled: false,
    type: 'button',
    text: 'Hello World',
    onClick: () => {},
  }
  const options = { ...baseProps, ...props }
  return (
    <button
      type={options.type}
      disabled={options.disabled}
      onClick={options.onClick}>
      {options.text}
    </button>
  )
}

Required

Required 的作用刚好与 Partial 相反,就是将接口中所有可选的属性改为必须的,区别就是把 Partial 里面的 ? 替换成了 -?。

// 其中-?是代表可移除?这个修改器的标识。
type Required<T> = {
    [P in keyof T]-?: T[P]
}

Record

``` ts

type petsGroup = 'dog' | 'ca