什么是 TypeScript 的条件类型?

2024-08-26 10:17:05 349
TypeScript 的条件类型(`Conditional Types`)是一种基于条件的类型系统,可以根据某个条件动态地选择和推导类型。条件类型类似于 JavaScript 中的三元表达式(`condition ? trueBranch : falseBranch`),但用于类型层面。

条件类型的语法

T extends U ? X : Y
  • T extends U:表示条件,如果 T 能赋值给 U,那么条件为真。
  • X:当条件为真时的返回类型。
  • Y:当条件为假时的返回类型。

示例 1: 基本条件类型

type IsString<T> = T extends string ? "Yes, it's a string" : "No, it's not a string";

type A = IsString<string>;  // "Yes, it's a string"
type B = IsString<number>;  // "No, it's not a string"

解释:

  • 如果 Tstring 类型,则返回 "Yes, it's a string"
  • 否则返回 "No, it's not a string"

示例 2: 条件类型结合泛型

你可以使用条件类型来创建灵活的类型推断。

type GetArrayType<T> = T extends (infer U)[] ? U : T;

type StringArray = GetArrayType<string[]>;  // string
type NumberArray = GetArrayType<number[]>;  // number
type NotArray = GetArrayType<string>;       // string

解释:

  • T extends (infer U)[] 表示检查 T 是否是数组类型,如果是数组,则推断数组元素的类型为 U,并返回 U
  • 如果 T 不是数组类型,则直接返回 T 本身。

示例 3: 使用条件类型的分发行为

条件类型在使用联合类型时会自动分发。

type ToArray<T> = T extends any ? T[] : never;

type StringArrayOrNumberArray = ToArray<string | number>;
// 等同于: string[] | number[]

解释:

  • string | number 被条件类型分发为 ToArray<string> | ToArray<number>,最终得到 string[] | number[]

示例 4: Exclude 和 Extract 内置条件类型

TypeScript 提供了几个基于条件类型的内置工具类型,如 ExcludeExtract

  • Exclude<T, U>:从 T 中排除所有可以赋值给 U 的类型。
  • Extract<T, U>:从 T 中提取所有可以赋值给 U 的类型。

示例:

type Excluded = Exclude<"a" | "b" | "c", "a">;  // "b" | "c"
type Extracted = Extract<"a" | "b" | "c", "a" | "c">;  // "a" | "c"

总结

条件类型为 TypeScript 提供了动态类型推断的能力,使类型系统更加灵活和强大。通过条件类型,你可以根据类型条件创建灵活的类型定义和推断,广泛应用于泛型、工具类型以及复杂类型的处理。