typescript泛型

我们平常是对值编程,而泛型是对类型编程

一、初识泛型

1.1 keyof

可以用来取得一个对象接口的所有 key 值

interface Foo {
  name: string;
  age: number;
}

type FooKeys = keyof Foo; // 'name' | 'age'

1.2 in

in 则可以遍历枚举类型

type Keys = "a" | "b";

type obj = {
  [p in Keys]: number;
};

let a: obj = {
  a: 1,
  b: 2,
};

1.3 infer

infer 这个关键字, 在条件类型语句中, 我们可以用 infer 声明一个类型变量并且对它进行使用

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function add(params: string) {
  return params;
}

type returnType = ReturnType<typeof add>;

infer R 就是声明一个变量来承载传入函数签名的返回值类型, 简单说就是用它取到函数返回值的类型方便之后使用.

1.4 Partial

Partial 作用是将传入的属性变为可选项.

源码:

type Partial<T> = { [P in keyof T]?: T[P] };

示例:

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

type newP = Partial<Person>;

// type newP = {
//     name?: string;
//     sex?: number;
//     age?: number;
// }

1.5 Required

Required 的作用是将传入的属性变为必选项

源码:

type Required<T> = { [P in keyof T]-?: T[P] };

示例:

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

type newP = Required<Person>;

// type newP = {
//     name: string;
//     sex: number;
//     age: number;
// }

1.6 Readonly

将传入的属性变为只读选项

源码:

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

示例:

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

type newP = Readonly<Person>;

// type newP = {
//     readonly name: string;
//     readonly sex?: number;
//     readonly age?: number;
// }

1.7 Record

将 K 中所有的属性的值转化为 T 类型

源码:

type Record<K extends keyof any, T> = { [P in K]: T };

示例:

interface PageInfo {
  title: string;
}

type Page = "home" | "about" | "contact";

const nav: Record<Page, PageInfo> = {
  about: { title: "about" },
  contact: { title: "contact" },
  home: { title: "home" },
};

1.8 Pick

从 T 中取出 一系列 K 的属性

源码:

type Pick<T, K extends keyof T> = { [P in K]: T[P] };

示例:

interface Person {
  name: string;
  age: number;
  visiable: boolean;
}
type Person1 = Pick<Person, "name" | "age">;

1.9 extends

条件类型

type TypeName<T> = T extends string
  ? "string"
  : T extends number
  ? "number"
  : T extends boolean
  ? "boolean"
  : T extends undefined
  ? "undefined"
  : T extends Function
  ? "function"
  : "object";

var a: TypeName<string> = "string";

1.10 Exclude

 提取出 T 不包含在 U 中的元素

源码:

type Exclude<T, U> = T extends U ? never : T

示例:

type A = number | string | boolean;
type B = number | boolean;

type newFoo = Exclude<A, B>;
// 相当于
// type Foo = string;

1.11 Extract

 Extract 的作用是提取出 T 包含在 U 中的元素

源码:

type Extract<T, U> = T extends U ? T : never;

示例:

type A = number | string | boolean
type B = number | boolean

type Foo = Extract<A, B>
// 相当于
type Foo = number | boolean

1.12 Omit

生成一个新类型,该类型拥有 T 中除了 K 属性以外的所有属性

源码:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>> 

示例:

type Foo = {
	name: string
	age: number
}

type Bar = Omit<Foo, 'age'>
// 相当于
type Bar = {
	name: string
}

二、类型

2.1 联合类型

满足其中之一的类型就可以了。

interface NAS {
  host: string;
  port: number;
}

interface OSS {
  key: string;
  secret: string;
  port: number;
}

type MyStorage = NAS | OSS;

const storage: MyStorage = { host: "127.0.0.1", port: 80 };

2.2 交叉类型

满足所有的情况

interface NAS {
  host: string;
  port: number;
}

interface OSS {
  key: string;
  secret: string;
  port: number;
}

type MyStorage = NAS & OSS;

const storage: MyStorage = { host: "127.0.0.1", port: 80, key: "", secret: "" };

2.3 条件类型

interface NAS {
  host: string;
  port: number;
}

interface OSS {
  key: string;
  secret: string;
  port: number;
}

enum StorageType {
  NAS,
  OSS,
}

type MyStorage<T> = T extends StorageType.NAS
  ? NAS
  : T extends StorageType.OSS
  ? OSS
  : never;

const myStorage: MyStorage<StorageType.NAS> = {
  host: "",
  port: 0,
};

三、应用

3.1. 交集

        交集的定义:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合。

type Intersection<T, U> = Pick<
  T,
  Extract<keyof T, keyof U> & Extract<keyof U, keyof T>
>;

interface NAS {
  host: string;
  port: number;
}

interface OSS {
  key: string;
  secret: string;
  port: number;
}

type JiaoJi = Intersection<NAS, OSS>;

3.2. 差集

差集的定义:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。

type Diff<T extends object, U extends object> = Pick<
  T,
  Exclude<keyof T, keyof U>
>;
type C1 = { name: string; age: number; visible: boolean };
type C2 = { name: string; age: number; sex: number };
type C11 = Diff<C1, C2>;

// type C11 = {
//     visible: boolean;
// }

3.3. 并集

对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。

type C1 = { name: string; age: number; visible: boolean };
type C2 = { name: string; age: number; sex: number };


type Compute<A extends any> = A extends Function ? A : { [K in keyof A]: A[K] };
type Merge<O1 extends object, O2 extends object> = Compute< O1 & Omit<O2, keyof O1>>;
type C1C2 = Merge<C1, C2>;

// type C1C2 = {
//     name: string;
//     age: number;
//     visible: boolean;
//     sex: number;
// }

覆盖并集

type C1 = { name: string; age: number; visible: boolean };
type C2 = { name: string; age: string; sex: number };

type Intersection<T, U> = Pick<
  T,
  Extract<keyof T, keyof U> & Extract<keyof U, keyof T>
>;
type Diff<T extends object, U extends object> = Pick<
  T,
  Exclude<keyof T, keyof U>
>;
type Overwrite<
  T extends object,
  U extends object,
  I = Diff<T, U> & Intersection<U, T>
> = Pick<I, keyof I>;
type overwrite = Overwrite<C1, C2>;

// type overwrite = {
//     name: string;
//     age: string;
//     visible: boolean;
// }

附录

参考连接:

https://www.typescriptlang.org/docs/handbook/utility-types.html

https://zhuanlan.zhihu.com/p/40311981

https://baijiahao.baidu.com/s?id=1717228098181547699&wfr=spider&for=pc

https://blog.csdn.net/azl397985856/article/details/106913210/

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值