TypeScript高级类型:映射类型与条件类型

TypeScript 是一种强类型编程语言,它在JavaScript的基础上增加了静态类型系统,使得开发者在开发阶段就能捕捉到更多潜在的错误。映射类型和条件类型是TypeScript中两种高级类型,它们提供了强大的抽象和类型推断能力,使你能够创建更复杂和灵活的类型定义。

映射类型

映射类型允许你基于现有类型创建新的类型,通过对类型属性进行转换或添加/删除属性来实现。映射类型的基本语法如下:

typescript 复制代码
type MappedType<T> = {
  [P in keyof T]: // 转换规则
};

在这个模板中,MappedType是一个新的类型,它基于类型T的所有键keyof T进行映射。P in keyof T是一个索引类型,它遍历T的所有属性键。然后,你可以根据需要对每个属性键P应用转换规则。

示例:只读映射类型

假设我们有一个对象类型Person,我们想要创建一个新的类型ReadOnlyPerson,其中所有属性都是只读的:

typescript 复制代码
type Person = {
  name: string;
  age: number;
};

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

type ReadOnlyPerson = ReadOnly<Person>;

在这个例子中,ReadOnly<T>类型定义了一个新的类型,其中T的所有属性都变成了只读属性。

示例:条件映射类型

映射类型也可以与条件类型一起使用,以根据条件应用不同的转换规则:

typescript 复制代码
type Nullable<T> = {
  [P in keyof T]?: T[P];
};

type RequiredNullable<T> = T extends object ? Nullable<T> : never;

在这个例子中,RequiredNullable类型只有在T是对象时才会将T的所有属性变为可选的;否则,它将返回never类型。

条件类型

条件类型允许你根据类型条件来选择不同的类型。条件类型的语法如下:

typescript 复制代码
type ConditionalType<T, U> = T extends U ? X : Y;

这里,T extends U是一个条件表达式,如果T可以赋值给U,则条件为真,类型X将被选择;否则,类型Y将被选择。

示例:Pick类型

Pick类型是从一个类型中挑选出特定的属性:

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

type Person = {
  name: string;
  age: number;
  gender: string;
};

type NameAndAge = Pick<Person, "name" | "age">;

在这个例子中,NameAndAge类型只包含Person类型中的nameage属性。

示例:Extract类型

Extract类型用于从联合类型中提取符合特定条件的类型成员:

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

type All = string | number | boolean;
type StringOrNumber = Extract<All, string | number>;

在这里,StringOrNumber类型将从All联合类型中提取出stringnumber类型。

综合应用

映射类型和条件类型可以结合使用,以创建更复杂的类型变换。例如,创建一个类型,该类型将对象中的所有属性变为可选,但保留特定属性为必需:

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

type Person = {
  name: string;
  age: number;
  gender: string;
};

type OptionalGenderPerson = MakeOptionalExcept<Person, "name" | "age">;

在这个例子中,OptionalGenderPerson类型将gender属性变为可选,但nameage属性仍然是必需的。

相关推荐
To_OC2 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC2 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic3 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy3 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志3 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble4 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长5 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯5 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜6 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司6 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能