TS 实现 Partial & Required & Readonly & Pick & Exclude & Extract & Omit
1. Partial 作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为可选项
type IPartial<T> = {
[key in keyof T]?:T[key]
}
interface Foo{
name:string;
}
type Bar = IPartial<Foo>;
2.Required 作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项
type IRequire<T> = {
[P in keyof T]-?: T[P]
}
interface Foo2 {
name: string
age?: number
}
type Bar1 = Required<Foo2>
3.Readonly 作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项
type IReadonly<T> = {
readonly [key in keyof T]-?:T[key]
}
interface Foo3 {
name: string
age: number
}
type Bar3 = IReadonly<Foo>
4.Pick 作用:生成一个新类型,该类型拥有 T 中的 K 属性
type IPick<T,K extends keyof T> = {
[P in K]:T[P]
}
interface Foo4 {
name: string
age?: number
gender: string
}
type Bar4 = IPick<Foo4, 'age' | 'gender'>
}
5. Exclude 作用:如果 T 是 U 的子类型则返回 never, 不是则返回 T, 求差集
type IExclude<T,U> = T extends U ? never : T
interface Foo5 {
name: string
age?: number
gender: string
}
interface Test {
name:string
}
type Bar5 = IExclude<'a'|'b'|'c', 'a'> // 'b'|'c'
type t1 = keyof Foo5
type t2 = keyof Test
type Bar6 = IExclude<t1, t2> // 'age'|'gender'
6.扩展 Diff,Filter
type Diff<T, U> = T extends U ? never : T;
type Filter<T, U> = T extends U ? T : never;
type T30 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;
type T31 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">;
let demo1: Diff<number, string>;
7.Extract 作用: 和 Exclude 相反, 求交集
type IInclude<T, U> = T extends U ? T : never;
type C1 = IInclude<'a'|'b'|'c','c'>
type IExtract<T,U> = T extends U ? T : never;
type A1 = number | string | boolean;
type A2 = number | boolean;
type B1 = IExtract<A1,A2>;
8.Omit 作用:生成一个新类型,该类型拥有 T 中除了 K 属性以外的所有属性
type IOmit<T,K extends keyof T> = IPick<T,IExclude<keyof T,K>>
interface Foo8 {
name: string
age: number
}
type Bar8 = IOmit<Foo8, 'age'>
9.type和interface区别
* 相同点:
* 1.都可以描述一个对象或者函数
* 2.都允许拓展(extends),虽然效果差不多,但是两者语法不同
* 不同点:
* 1.type 可以声明基本类型别名,联合类型,元组等类型,interface不行;
* 2.type 语句中还可以使用 typeof 获取实例的 类型进行赋值,interface不行;
* 3.interface 能够声明合并,type不行
type Name = {
name: string;
}
type User = Name & { age: number };
let obj: User = {
name: 'll',
age: 12
}
let div = document.createElement('div');
type B = typeof div
type str = 'a' | 'b' | 'c';
let s:str = 'a'
interface Person {
name: string
age: number
}
interface Person {
sex: string
}
type Hobby = {
hobby:string;
}
interface Person extends Hobby{}
let p:Person = {
name:'mark',
age:12,
sex:'male',
hobby:'旅游'
}