当前位置: 首页 > news >正文

神奇的TypeScript -- 进阶篇之实用工具类型

系列文章目录

神奇的TypeScript – 基础篇


文章目录

  • 系列文章目录
  • 前言
  • 一、运算符和分布式联合类型
  • 二、实用工具类型
    • 1. 修改已有的类型属性:Partial|Required|Readonly
      • 1.1 用法
      • 1.2 代码示例
      • 1.3 手动实现一个Partial
    • 2. 选择或剔除类型中的属性:Pick|Omit
      • 2.1 Pick
        • 2.1.1 用法
        • 2.1.2 手动实现一个Pick
      • 2.2 Omit
        • 2.2.1 用法
        • 2.2.2 手动实现一个 Omit
    • 3. Record
      • 3.1 用法
      • 3.2 手动实现一个 Record
    • 4. Extract | Exclude
      • 4.1 Extract
        • 4.1.1 用法
        • 4.1.2 手动实现
      • 4.2 Exclude
        • 4.2.1 用法
        • 4.2.2 手动实现
    • 5. ReturnType | Parameters
      • 5.1 ReturnType
        • 5.1.1 用法
        • 5.1.2 手动实现
      • 5.2 Parameters
        • 5.2.1 用法
        • 5.2.2 手动实现
    • 6. InstanceType | ConstructorParameters
      • 6.1 InstanceType
      • 6.1.1 用法
      • 6.1.2 手动实现
      • 6.2 ConstructorParameters
        • 6.2.1 用法
    • 7. NonNullable
      • 7.1 用法
      • 7.2 手动实现
  • 总结


前言

TypeScript作为一个强类型语言,TypeScript 为我们也提供了很多实用工具类型,让我们可以以一种方便的方式来操作现有类型并从中创建新类型。他们可以帮助我们更轻松地描述常见类型转换,提高代码的可读性和可维护性。

一、运算符和分布式联合类型

我们先来了解一下基础的几个运算符,这几个运算符我们在后面会经常用到:

keyof: 获取类型中的所有属性名称key,返回一个包含所有属性名称的联合类型。
typeof: 获取类型。
in:遍历,可以用来遍历联合类型。
extends:
1. 用来声明类继承,A extends B也就是A继承B;
2. 定义条件类型,C extends D ? C : nerve即遍历C(联合类型)与D进行比较,如果相同则保留,返回一个不包含D类型的的C类型
infer: infer 只能在条件类型的 extends 子句中使用,用来提取类型信息,并且声明的类型变量只能在条件类型的真值分支中使用。

以及一个特殊的类型判断:
分布式联合类型:当条件类型遇到联合类型时,它会把条件类型应用于联合类型中的每个成员,然后将结果合并成一个新的联合类型。

type DAD<T> = T extends () => infer U ? U : never;

二、实用工具类型

我们先定义一个Person的接口类型

interface Person {name: string;age: number;height?: number;what?: null;why: undefined;sayHello(): void;
}

1. 修改已有的类型属性:Partial|Required|Readonly

Partial 将所有属性改为可选属性。
Required 将所有属性改为必填属性。
Readonly 将所有属性改为只读属性。

1.1 用法

Partial<Type>
Required<Type>
Readonly<Type>

Type:想要修改的类型

1.2 代码示例

// 将所有属性变为可选
type PersonPartial = Partial<Person>;
// 将所有属性变为必选
type PersonRequired = Required<Person>;
// 将所有属性变为只读
type PersonReadonly = Readonly<Person>;const o: PersonPartial = {}
const p: PersonRequired = {name: "",sayHello: function (): void {throw new Error("Function not implemented.");},age: 0,height: 0,what: null,why: undefined
};
const q: PersonReadonly = {name: "",sayHello: function (): void {throw new Error("Function not implemented.");},age: 0,why: undefined
};

1.3 手动实现一个Partial

// 实现一个Partial
type PersonPartialCopy<T> = {[k in keyof T]: T[k];
}const PPC: PersonPartialCopy<Person> = {name: "",sayHello: function (): void {throw new Error("Function not implemented.");},age: 0,why: undefined
}

2. 选择或剔除类型中的属性:Pick|Omit

Pick 用于从类型中选取指定的属性。
Omit 用于从类型中排除指定的属性。

2.1 Pick

选择类型中的属性

2.1.1 用法
Pick<Type, Keys>

Type: 要选取属性的类型。
Keys: 要选取的属性的键的联合类型。

type PersonPick = Pick<Person, "name" | "age">;
2.1.2 手动实现一个Pick
type PersonPickRealize<T, K extends keyof T> = {[k in K]: T[k];
}
const PPR: PersonPickRealize<Person, "name" | "age"> = {name: "",age: 0
}

2.2 Omit

剔除类型中的属性

2.2.1 用法
Omit<Type, Keys>

Type: 要排除属性的类型。
Keys: 要排除的属性的键的联合类型。

type PersonOmit = Omit<Person, "name">;
2.2.2 手动实现一个 Omit
type PersonOmitRealize<T, K extends keyof T> = {[k in Exclude<keyof T, K>]: T[k]
}
const POR: PersonOmitRealize<Person, "name"> = {age: 0,sayHello: () => { },height: undefined,what: undefined,why: undefined
}

3. Record

Record用来构造一个所有属性都相同类型的类型

3.1 用法

type PersonRecord = Record<"name" | "age", string>;

3.2 手动实现一个 Record

type PersonRecordRealize<K extends keyof any, T> = {[k in K]: T;
}
let s: Symbol = Symbol(1);
const PRR: PersonRecordRealize<"name" | 123, string> = {name: "",123: ""
}

4. Extract | Exclude

选择联合类型类型中的类型

4.1 Extract

4.1.1 用法
type PersonExtract = Extract<Person | string, Person>;
4.1.2 手动实现
const PEE: PersonExtract = {name: "",sayHello: () => { },age: 0,why: undefined
}

4.2 Exclude

剔除联合类型中的一些类型

4.2.1 用法
type PersonExclude = Exclude<Person | string, Person>;
4.2.2 手动实现
type PersonExcludeRealize<T, U> = T extends U ? never : T;
const PE: PersonExclude = "123";

5. ReturnType | Parameters

function foo(a: number, b: string): boolean { return false; }

5.1 ReturnType

获取函数函数返回类型

5.1.1 用法
type FooReturnType = ReturnType<typeof foo>;
5.1.2 手动实现
type ReturnTypeRealize<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never;

5.2 Parameters

获取函数参数类型,返回一个元组

5.2.1 用法
type FooParameters = Parameters<typeof foo>;
5.2.2 手动实现
type FooParametersRealize<T extends (...args: any) => any> = T extends (...args: infer U) => any ? U : never;
class Animal {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}sayHello() {console.log(`Hello, my name is ${this.name}`);}
}

6. InstanceType | ConstructorParameters

6.1 InstanceType

构造函数类型的实例类型

6.1.1 用法

type AnimalInstanceType = InstanceType<typeof Animal>;

6.1.2 手动实现

type AnimalInstanceTypeRealize<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
const AI: AnimalInstanceTypeRealize<typeof Animal> = new Animal("", 0);

6.2 ConstructorParameters

构造函数的类型来构造元组或数组类型

6.2.1 用法
type AnimalConstructorParameters = ConstructorParameters<typeof Animal>;

7. NonNullable

去除联合类型中的null和undefined

7.1 用法

type PersonNonNullable = NonNullable<undefined | null | string>;
const PNN: PersonNonNullable = "123";

7.2 手动实现

type PersonNonNullableRealize<T> = T extends null | undefined ? never : T;
const ONNR: PersonNonNullableRealize<undefined | null | string> = "123";

总结

TypeScript 的实用工具类型是预定义的类型函数,提供对现有类型的便捷转换和操作。可以轻松地创建新类型或修改现有类型,而无需手动编写冗长的类型定义。∂∂∂

  • 提高代码可读性: 提供简洁的语法来表达常见的类型转换,使代码更易于阅读和理解。
  • 增强类型安全性: 通过提供类型检查来帮助您避免常见的类型错误,从而提高代码的可靠性。
  • 简化类型定义: 可以减少需要编写的类型定义代码量,从而提高开发效率。

总而言之,TypeScript 的实用工具类型是编写类型安全、清晰且表达能力强的代码的有力工具。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 原神自定义倒计时
  • Codeforces Round 960 (Div. 2)-补题
  • Web 搜索引擎优化
  • AI论文速读 | 2024MM【开源】时间序列预测中频率动态融合
  • 【Python机器学习】支持向量机——手写数字识别问题
  • 深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
  • 反激式电源为什么上电最容易烧MOS管?
  • python dash框架
  • 【linux深入剖析】初识线程---线程概念
  • JavaEE-多线程编程阻塞队列
  • 探索之路——初识 Vue Router:构建单页面应用的完整指南
  • 网络空间安全专业怎么样,可通过哪些途径自学?
  • 【Redis】 Redis 列表指令指南
  • python open cv(图像处理的基本操作)
  • Spring Bean生命周期
  • android图片蒙层
  • canvas 绘制双线技巧
  • CSS盒模型深入
  • CSS中外联样式表代表的含义
  • Git的一些常用操作
  • PAT A1092
  • PHP的Ev教程三(Periodic watcher)
  • vue数据传递--我有特殊的实现技巧
  • 编写符合Python风格的对象
  • 从输入URL到页面加载发生了什么
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 简单基于spring的redis配置(单机和集群模式)
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​ssh免密码登录设置及问题总结
  • ​VRRP 虚拟路由冗余协议(华为)
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • # 数据结构
  • #window11设置系统变量#
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (二)c52学习之旅-简单了解单片机
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (三)Honghu Cloud云架构一定时调度平台
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十五)使用Nexus创建Maven私服
  • (一)为什么要选择C++
  • (转载)CentOS查看系统信息|CentOS查看命令
  • ./和../以及/和~之间的区别
  • .cn根服务器被攻击之后
  • .net 8 发布了,试下微软最近强推的MAUI
  • .net core 6 redis操作类
  • .NET 中创建支持集合初始化器的类型
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .net分布式压力测试工具(Beetle.DT)