高级类型

TypeScript 提供了丰富的高级类型特性,让我们可以创建复杂且灵活的类型定义。高级类型包括交叉类型、联合类型、类型守卫、类型别名、字面量类型、可辨识联合、索引类型、映射类型和条件类型等。

交叉类型

交叉类型将多个类型合并为一个类型,新类型拥有所有类型的特性。

interface Name {
  name: string
}

interface Age {
  age: number
}

type Person = Name & Age

const person: Person = {
  name: "张三",
  age: 25
}

console.log(person.name, person.age)

Person 类型同时具有 nameage 属性。

联合类型

联合类型表示一个值可以是多种类型之一。

type StringOrNumber = string | number

function format(value: StringOrNumber): string {
  if (typeof value === "string") {
    return value.toUpperCase()
  }
  return value.toFixed(2)
}

console.log(format("hello"))
console.log(format(3.14159))

StringOrNumber 可以是字符串或数字。

类型守卫

类型守卫用于在运行时检查类型,帮助 TypeScript 确定变量的具体类型。

interface Bird {
  fly(): void
}

interface Fish {
  swim(): void
}

function move(animal: Bird | Fish) {
  if ("fly" in animal) {
    animal.fly()
  } else {
    animal.swim()
  }
}

in 操作符检查对象是否有某个属性,帮助区分类型。

类型别名

类型别名给类型起一个新名字,可以用于原始类型、联合类型、交叉类型等。

type ID = string | number
type Point = {
  x: number
  y: number
}

function getPosition(): Point {
  return { x: 100, y: 200 }
}

const id: ID = "user-001"

类型别名让复杂类型更易读。

字面量类型

字面量类型指定具体的值,而不是类型范围。

type Direction = "up" | "down" | "left" | "right"

function move(direction: Direction): void {
  console.log(`向 ${direction} 移动`)
}

move("up")
move("down")

Direction 只能是四个字符串值之一。

可辨识联合

可辨识联合结合了联合类型和字面量类型,用于处理多种相关类型。

interface Circle {
  kind: "circle"
  radius: number
}

interface Rectangle {
  kind: "rectangle"
  width: number
  height: number
}

type Shape = Circle | Rectangle

function getArea(shape: Shape): number {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius * shape.radius
    case "rectangle":
      return shape.width * shape.height
  }
}

kind 属性是可辨识标签,帮助区分不同的形状类型。

索引类型

索引类型让我们可以查询和操作类型的属性类型。

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key]
}

const user = {
  name: "张三",
  age: 25
}

console.log(getProperty(user, "name"))
console.log(getProperty(user, "age"))

keyof T 获取 T 的所有键的联合类型。

映射类型

映射类型可以从旧类型创建新类型。

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

interface User {
  name: string
  age: number
}

type ReadonlyUser = Readonly<User>

const user: ReadonlyUser = {
  name: "张三",
  age: 25
}

Readonly<T> 将所有属性变为只读。

条件类型

条件类型根据条件选择类型。

type NonNullable<T> = T extends null | undefined ? never : T

type StringOrNumber = string | number
type Result = NonNullable<StringOrNumber | null>

function process(value: NonNullable<string | null>): string {
  return value.toUpperCase()
}

console.log(process("hello"))

NonNullable<T> 排除 nullundefined

小结

TypeScript 的高级类型提供了强大的类型操作能力。交叉类型合并多个类型,联合类型表示多种可能,类型守卫帮助区分类型,类型别名简化复杂类型,字面量类型限制具体值,可辨识联合处理相关类型,索引类型操作属性类型,映射类型转换类型,条件类型根据条件选择类型。掌握这些高级类型可以编写更加灵活和安全的代码。