作用:Partial将类型的属性变成可选的
举例
假如现在有个interface
interface IActivityItem {
id: number;
title: string;
links: string;
}
然后某一天我想把IActivityItem身上的属性变成可选的,那可能就会再写一个Interface
interface IActivityItem2 {
id?: number;
title?: string;
links?: string;
}
但是如果属性过多的话,就得写很多额外的代码,这个时候就可以用Partial
type IActivityItem2 =Partial<IActivityItem>
//等同于
interface IActivityItem2 {
id?: number;
title?: string;
links?: string;
}
原理
type Partial<T> = {
[P in keyof T]?: T[P];
};
那么 Partial<T> 是如何实现类型转化的呢?
遍历入参 T ,获得每一对 key, value
将每一对中的 key 变为可选,即添加 ?
希望得到的是由 key, value 组成的新类型
以上对应到 TypeScript 中是如何实现的呢?
keyof
keyof,即 索引类型查询操作符,我们可以将 keyof 作用于泛型 T 上来获取泛型 T 上的所有 public 属性名构成的 联合类型
例如
type unionKey = keyof IActivityItem
// unionKey 结果如下,其获得了接口类型 IUser 中的所有属性名组成的联合类型
type unionKey = "id" | "title" | "links"
in
我们需要遍历 IActivityItem ,这时候 映射类型就可以用上了,其语法为 [P in Keys]
T[P]
我们可以通过 keyof 查询索引类型的属性名,那么如何获取属性名对应的属性值类型呢?
这里就用到了 索引访问操作符,与 JavaScript 种访问属性值的操作类似,访问类型的操作符也是通过 [] 来访问的,即 T[P],其中”中括号“中的 P 与 [P in keyof T] 中的 P 相对应。
例如
type unionKey = keyof IActivityItem // "id" | "title" | "links"
type values = IActivityItem[unionKey] // number|string|string 属性值类型组成的联合类型
最后我们希望得到的是由多个 key, value 组成的新类型,故而在 [P in keyof T]?: T[P]; 外部包上一层大括号。
作用:和Partial刚好相反,Required 将类型的属性变成必选
举例
假如有一个interface
interface IActivityItem {
id: number;
title?: string;
links?: string;
}
某一天我想把里面的属性全变为必选的,我就会重新写一个interface
interface IActivityItem2 {
id: number;
title: string;
links: string;
}
但如果我用Required就会方便很多
type IActivityItem2 = Required<IActivityItem>
//等同于
interface IActivityItem2 {
id: number;
title: string;
links: string;
}
原理
type Required<T> = {
[P in keyof T]-?: T[P]
};
作用:从某个类型中挑出一些属性出来
举例
假如有一个interface
interface IActivityItem {
id: number;
title: string;
links: string;
start_time: number;
end_time: number;
live_time: number;
index: number;
}
某一天,我想要一个新的interface,他只拥有id,titlle这两个属性,那我会重写一个interface
interface IActivityItem2 {
id: number;
title: string;
}
但如果使用Pick非常方便去实现
type IActivityItem2 = Pick<IActivityItem,'id','title'>
//等同于
interface IActivityItem2 {
id: number;
title: string;
}
原理
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
作用:与Pick相反,Pick用于拣选出我们需要关心的属性,而Omit用于忽略掉我们不需要关心的属性
举例
假如有一个interface
interface IActivityItem {
id: number;
title: string;
links: string;
}
现在我想要重新写一个interface,它只有id, title两个属性
interface IActivityItem2 {
id: number;
title: string;
}
那么这个时候Omit就派上用场了
type IActivityItem2 =Omit<IActivityItem,'links'>
//等同于
interface IActivityItem2 {
id: number;
title: string;
}
原理
type Omit<T, K extends keyof any> =
Pick<T, Exclude<keyof T, K>>;
作用:Readonly 的作用是将某个类型所有属性变为只读属性,也就意味着这些属性不能被重新赋值。
举例
interface Person {
readonly id: number;
name: string;
age?: number;
}
let tom: Person = {
id: 89757,
name: 'Tom',
gender: 'male'
};
tom.id = 9527; // Cannot assign to 'id' because it is a constant or a read-only property
原理
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
作用:是用来过滤类型中的null及undefined类型
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
原理
type NonNullable<T> = T extends
null | undefined
? never : T;