TypeScript 工具泛型教程示例

 更新时间:2023年09月26日 10:53:22   作者:卡卡  
这篇文章主要为大家介绍了TypeScript 工具泛型教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

Typescript 中默认内置了很多工具泛型,通过使用这些工具,可以使得我们定义类型更加灵活,高效。本文将会介绍常用泛型工具的使用技巧,以及对其实现原理进行相应的解析,如果有错误的地方,还望指出。

Partial\<T>

作用:将传入对象类型 T 的属性变为可选属性

示例

interface Person {
  name: string;
  age: number;
}
const tom: Partial<Person> = {
  name: "Tom",
};javascript:void(0)

Partial<Person> 等价于

interface Person {
  name?: string;
  age?: number;
}

实现原理

  • 通过关键字 keyof 将传入对象类型的键值转换为联合类型。
  • 通过关键字 in 遍历联合类型,即遍历对象的键值。
  • 通过类型映射,将对象的属性转换为可选属性
type MyPartial<T> = {
  [P in keyof T]?: T[P];
};

Readonly\<T>

作用:把传入对象类型 T 属性变为只读属性

示例

interface Person {
  name: string;
  age: number;
}
const tom: Readonly<Person> = {
  name: "Tom",
  age: 18;
};
tom.age = 22 // error

Readonly<Person> 等价于

interface Person {
  readonly name: string;
  readonly age: number;
}

实现原理

Partial类似:

  • 通过关键字 keyof 将传入对象类型的键值转换为联合类型。
  • 通过关键字 in 遍历联合类型,即遍历对象的键值。
  • 通过类型映射,将对象的属性转换为只读属性
type Readonly<T> = {
  [P in keyof T]-?: T[P];
};

Required\<T>

作用:把传入对象类型 T 属性变为必填属性

示例

interface Person {
  name?: string;
  age?: number;
}
let tom: Required<Person>
tom = {
  name: "Tom",
  age: 18;
};
// ok
tom = {
  name: "Tom",
};
// error

实现原理

Partial类似:

  • 通过关键字 keyof 将传入对象的键值转换为枚举类型。
  • 通过关键字 in 遍历枚举类型,即遍历对象的键值。
  • 通过类型映射,再统一通过 -? 修饰符移除 ? 修饰符,从而转变为必填状态
type Required<T> = {
  Required [P in keyof T]: T[P];
};

Record\<K,T>

作用:它用来生成一个属性名为 K,属性值类型为 T 的对象类型集合。

示例

// 快速生成一个 Person 对象
type Person = Record<"name" | "country", string>;
const Tom: Person = { name: "Tom", country: "America" };

实现原理:

  • 通过 K extends keyof any 对 K 参数进行约束,将其约束为任意类型 any 的键值。
  • 通过 in 对键值集合 K 进行遍历,然后生成类型为 T 的键值对集合。
type MyRecord<K extends keyof any, T> = {
  [P in K]: T;
};

Exclude\<T,K>

作用:从类型 T 中排除所有可以赋值给类型 U 的类型。

示例

// 从 "a" | "b" | "c" 中排除掉 "a" 类型
type T1 = Exclude<"a" | "b" | "c", "a">;
// T1 = "b" | "c"
// 从 string | number | boolean 中排除掉 string 类型
type T2 = Exclude<string | number | boolean, string>;
// T2 = number | boolean

实现原理

  • 通过条件类型T extends U ? never : T 对 T 参数进行判别:

    • 如果 T 可赋值给 U ,那么返回 never(即排除掉T)。
    • 如果 T 不可赋值给 U ,那么返回 T
  • 通过分布式条件类型,如果 T 为联合类型,则将条件类型的结果分发为联合类型
type Exclude<T, U> = T extends U ? never : T;

Extract\<T,K>

作用:与 Exclude 相反,从类型 T 中提取所有可以赋值给类型 U 的类型。

示例

// 从 "a" | "b" | "c" 中提取出 "a" 类型
type T1 = Extract<"a" | "b" | "c", "a">;
// T1 = "a"
// 从 string | number | boolean 中提取出 string 类型
type T2 = Extract<string | number | boolean, string>;
// T2 = string
type T3 = Extract<string | (() => void), Function>;
// 相当于 type T3 = () => void;

实现原理

与 Exclude 类似:

  • 通过条件类型T extends U ? never : T 对 T 参数进行判别:

    • 如果 T 可赋值给 U ,那么返回 T
    • 如果 T 不可赋值给 U ,那么返回 never(即排除掉T)。
  • 通过分布式条件类型,如果 T 为联合类型,则将条件类型的结果分发为联合类型
type Extract<T, U> = T extends U ? T : never;

Pick\<T,K>

作用:在 T 中,摘选出 K 属性。

示例

interface Person {
  name: string;
  age: number;
}
// 从 Person 中摘选出 name 属性
type PickPerson = Pick<Person, "name">;
const tom: PickPerson = {
  name: "Tom",
};

实现原理

  • 通过 K extends keyof T 对 K 参数进行约束,将其约束为 T 的键值范围内。
  • 通过 in 对键值集合 K 进行遍历,然后生成类型为 T 的键值对集合。
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

Omit\<T,K>

作用:在 T 中,剔除掉 K 属性。

示例

interface Person {
  name: string;
  age: number;
}
// 从 Person 中剔除掉 name 属性
type OmitPerson = Omit<Person, "name">;
const tom: OmitPerson = {
  age: 18,
};

实现原理

  • 通过 K extends keyof T 对 K 参数进行约束,将其约束为 T 的键值范围内。
  • 通过 Exclude<keyof T, K> 将类型集合 T 中的 K 类型排除掉。
  • 通过 Pick<T,Exclude<keyof T, K>> 在 T 中摘选出排除掉 K 的 T 的属性。
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

ReturnType\<T>

作用:获取函数的返回值类型。

示例

type Fun = () => string;
// 获取 Fun 返回值的类型
type T1 = ReturnType<Fun>; // T1 = string
type T2 = ReturnType<() => { x: number; y: number }>;
// T2 = { x: number, y: number }

实现原理

  • 通过 extends 对 T 参数进行约束,(...args: any) => any 表示一个函数类型,即 T 参数的类型必须是一个函数类型
  • T extends U ? X : Y 是条件类型(注意和之前表示约束的 extends 做区分),其中 T 是泛型参数,U 是条件部分X 是符合条件的返回结果,Y 是不符合条件的返回结果。
  • 推断类型 infer 的作用是:在条件类型内部声明一个类型变量(...args: any) => infer R 是条件类型的条件部分,它声明了一个类型变量 R ,用来存储函数的返回类型。
  • T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any表示:

    • 如果 T 是函数类型((...args: any) => infer R),则返回 R , 即函数的返回类型。
    • 如果 T 不是函数类型((...args: any) => infer R),则返回 any
type ReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;

参考资料

以上就是TypeScript 工具泛型教程示例的详细内容,更多关于TypeScript 工具泛型的资料请关注脚本之家其它相关文章!

相关文章

  • 浅谈Javascript数据属性与访问器属性

    浅谈Javascript数据属性与访问器属性

    下面小编就为大家带来一篇浅谈Javascript数据属性与访问器属性。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • js动态生成唯一id的三种方法

    js动态生成唯一id的三种方法

    这篇文章主要介绍了js动态生成唯一id的两种方法,需要的朋友可以参考下
    2023-05-05
  • canvas学习之API整理笔记(一)

    canvas学习之API整理笔记(一)

    本文主要介绍了canvas的相关知识。canvas本身很简单,就是去学习它的API,多看实例,多自己动手练习,多总结。本文介绍了很多小例,具有一定的参考价值,下面跟着小编一起来看下吧
    2016-12-12
  • 使用requestAnimationFrame实现js动画性能好

    使用requestAnimationFrame实现js动画性能好

    requestAnimationFrame优于setTimeout/setInterval的地方在于它是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销,这篇文章给大家详细介绍使用requestAnimationFrame实现js动画
    2015-08-08
  • Bootstrap Table 搜索框和查询功能

    Bootstrap Table 搜索框和查询功能

    这篇文章主要介绍了Bootstrap Table 搜索框和查询功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • JavaScript定义全局对象的方法示例

    JavaScript定义全局对象的方法示例

    这篇文章主要介绍了JavaScript定义全局对象的方法,结合实例形式分析了javascript全局对象的简单定义流程与实现技巧,需要的朋友可以参考下
    2017-01-01
  • javascript 容错处理代码(屏蔽js错误)

    javascript 容错处理代码(屏蔽js错误)

    有时候大家来浏览网页的时候发现IE浏览器左下角总有个黄色错误标志,有时候更是直接弹出错误无法继续浏览页面,这样对于网站的正规性与权威性发展不利。
    2010-04-04
  • 微信小程序下拉框搜索功能的实现方法

    微信小程序下拉框搜索功能的实现方法

    这篇文章主要介绍了微信小程序下拉框搜索功能的实现方法,内容比较简单容易理解 ,需要的朋友可以参考下
    2019-07-07
  • JavaScript实现简单的四则运算计算器完整实例

    JavaScript实现简单的四则运算计算器完整实例

    这篇文章主要介绍了JavaScript实现简单的四则运算计算器,结合完整实例形式分析了javascript基于表单相应实现加减乘除数学运算的操作技巧,需要的朋友可以参考下
    2017-04-04
  • js get和post请求实现代码解析

    js get和post请求实现代码解析

    这篇文章主要介绍了js get和post实现代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02

最新评论