【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 参数的值返回 ThenElse 中的一个。在这里,由于条件是 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 条件类型的更多应用,包括属性提取、类型排除、数组操作和函数参数检查。条件类型可以帮助你在类型级别执行复杂的操作,从而增强代码的类型安全性和可维护性。

相关推荐
@@@@@@@@546 小时前
JavaScript 的缺点与 TypeScript 的弥补
开发语言·javascript·typescript
用户0934077735148 小时前
HarmonyOS WPS Open SDK 实践:最小打开闭环与 enableEdit 分支处理
typescript·harmonyos
柯克七七1 天前
我把 bug 修得太干净了,测试组以为这个模块本来就没问题
前端·javascript·typescript
退休倒计时1 天前
【每日一题】LeetCode 39. 组合总和 TypeScript
算法·leetcode·typescript
yyt3630458411 天前
KlineChartQuant Tooltip 高频交互 200FPS 性能优化完整复盘
前端·经验分享·性能优化·typescript·vue·交互·chrome devtools
用户0934077735141 天前
HarmonyOS WPS Open SDK 实践:办公审批附件「打开—编辑—回传」代码实现
typescript·harmonyos
Flynt1 天前
TypeScript 5.8 让我少踩了一个大坑,顺手再聊聊 --erasableSyntaxOnly
前端·javascript·typescript
退休倒计时2 天前
【每日一题】LeetCode 17. 电话号码的字母组合 TypeScript
算法·leetcode·typescript
无情的西瓜皮3 天前
MCP 协议实战:从零搭建一个 MCP 服务器(Node.js 版)
vue.js·人工智能·typescript·node.js
退休倒计时3 天前
【每日一题】LeetCode 78. 子集 TypeScript
算法·leetcode·typescript