【TypeScript】条件类型

TypeScript 条件类型(Conditional Types)是一种高级类型工具,允许基于一个条件来选择两种不同的类型之一。条件类型的使用通常结合泛型类型参数,能够在类型系统中进行复杂的条件分支操作。条件类型的通用形式如下:

typescript 复制代码
T extends U ? X : Y
  • T 是待检查的类型。
  • U 是要检查是否可分配给 T 的类型。
  • 如果 T 可以赋值给 U,则条件类型的结果是 X,否则是 Y。

1、可选属性的条件类型

考虑一个使用条件类型来创建可选属性的示例:

typescript 复制代码
type MakePropertyOptional<T, K extends keyof T> = {
    [P in K]: T[P];
} & {
    [P in Exclude<keyof T, K>]?: T[P];
};

type OriginalType = {
    name: string;
    age: number;
};

type UpdatedType = MakePropertyOptional<OriginalType, 'age'>;

定义了一个条件类型 MakePropertyOptional,它接受两个类型参数:T 是原始类型,K 是属性名的联合类型。它的工作原理如下:

  • MakePropertyOptional<OriginalType, 'age'> 将 OriginalType 的属性按照 K 的分组分为两部分,一部分包括 age 属性,另一部分包括其余属性。
  • age 属性保持不变,而其他属性被标记为可选(?)。

2、联合类型的条件类型

考虑一个使用条件类型来过滤联合类型的示例:

typescript 复制代码
type FilterByType<T, U> = T extends U ? T : never;

type OriginalUnion = string | number | boolean;
type FilteredUnion = FilterByType<OriginalUnion, string>;

在这个示例中,FilterByType 条件类型将筛选出 OriginalUnion 联合类型中的符合条件的类型。在这里,我们只选择了字符串类型,所以 FilteredUnion 的类型将是 string。

3、根据条件选择返回类型

这个示例演示了如何使用条件类型根据条件选择返回类型:

typescript 复制代码
type If<Condition extends boolean, Then, Else> = Condition extends true ? Then : Else;

type Result = If<true, 'Yes', 'No'>; // Result 类型为 'Yes'

If 是一个自定义条件类型,它根据 Condition 参数的值返回 Then 或 Else 中的一个。在这里,由于条件是 true,所以 Result 的类型是 'Yes'。

这些示例展示了 TypeScript 条件类型的多种应用,包括属性操作、类型过滤和条件分支。它们允许你在类型级别进行复杂的判断和操作,提高了代码的类型安全性和可读性。 当使用 TypeScript 的条件类型时,你可以执行许多复杂的类型操作。以下是更多示例,每个示例都详细描述其目的和工作原理:

4、从对象类型中提取特定属性类型

假设你有一个包含不同属性类型的对象,并且你想从中提取特定属性的类型。你可以使用条件类型来实现这一点:

typescript 复制代码
type ExtractPropertyType<T, K> = T extends { [key: string]: infer U } ? U : never;

type MyObject = {
    name: string;
    age: number;
    isValid: boolean;
};

type AgeType = ExtractPropertyType<MyObject, 'age'>; // AgeType 类型为 number

在这个示例中,ExtractPropertyType 条件类型根据属性名 K 从对象类型 T 中提取对应属性的类型。

5、根据条件从联合类型中排除特定类型

有时你可能想从联合类型中排除特定的类型。条件类型可以帮助你实现这一点:

typescript 复制代码
type ExcludeType<T, U> = T extends U ? never : T;

type OriginalUnion = string | number | boolean;
type WithoutNumbers = ExcludeType<OriginalUnion, number>;

在这个示例中,ExcludeType 条件类型将从 OriginalUnion 联合类型中排除了 number 类型,所以 WithoutNumbers 的类型将是 string | boolean。

6、根据数组元素类型构建新数组类型

你可以使用条件类型来构建新数组类型,其中的每个元素类型都是给定类型的属性类型:

typescript 复制代码
type ArrayElementType<T> = T extends (infer U)[] ? U : never;

type MyArray = [string, number, boolean];
type Element = ArrayElementType<MyArray>; // Element 类型为 string | number | boolean

在这个示例中,ArrayElementType 条件类型将从数组类型 T 中提取元素类型,这对于操作数组类型非常有用。

7、使用条件类型进行函数参数检查

条件类型可以用于检查函数的参数类型,并根据不同的条件执行不同的操作:

typescript 复制代码
type CheckParams<T> = T extends (...args: infer Args) => any
    ? Args
    : never;

function printLength(arr: number[]) {
    const length = arr.length;
    console.log(`Array length: ${length}`);
}

type Params = CheckParams<typeof printLength>; // Params 类型为 [number[]]

在这个示例中,CheckParams 条件类型从函数类型 T 中提取参数类型。这可以用来在编译时检查函数的参数类型。

这些示例展示了 TypeScript 条件类型的更多应用,包括属性提取、类型排除、数组操作和函数参数检查。条件类型可以帮助你在类型级别执行复杂的操作,从而增强代码的类型安全性和可维护性。

相关推荐
濮水大叔8 小时前
NestJS Dynamic Providers 与 Cabloy/Vona Provider Scene:同接口多实现的两种装配哲学
typescript·node.js·nestjs
const_qiu12 小时前
第一章 1.1-1.2:基础模型调用与 TypeScript 入门 —— Java 开发者的视角
java·javascript·typescript
ZoeLandia15 小时前
TypeScript 03:泛型与工具类型
前端·typescript
ZoeLandia16 小时前
TypeScript 05:交叉类型、索引签名、元组与 enum
前端·typescript
孟陬19 小时前
利用 TypeScript `asserts` function 语法定制一个类型缩窄的 `assertIncludes`
typescript·node.js
damoluomu19 小时前
静态站点生成器怎么选:Node.js 生态里常用的五个(番外一)
javascript·css·typescript·node.js·html
ZoeLandia20 小时前
TypeScript 04:类型断言与类型守卫
开发语言·前端·typescript
濮水大叔20 小时前
Cabloy/Vona 如何避开 NestJS 的循环依赖问题:懒属性注入机制源码解析
typescript·node.js·nestjs
雨雨雨雨雨别下啦2 天前
【OpenHarmony北向开发】ArkTS基础教学
typescript·arkts·openharmonys
ZoeLandia2 天前
TypeScript 01:类型注解与类型推断
前端·javascript·typescript