目录
1.Partial 转化可选属性 (?) 2.Required 转化必填属性 (-?) 3.Readonly 转化仅读属性 (readonly) Mutate(非内置,与 Readonly 相对) (-readonly) 4.Pick 挑选所需的属性 5.Omit 忽略属性在前几章的笔记中,了解了以下几种内置类型:
条件类型相关: Exclude 排除类型(差集) , Extract 抽取类型(交集) , NoNullable 非空检测 ,
infer 类型推导相关: ReturnType 返回值类型 , Parameters 参数类型 , InstanceType 实例类型 , ConstructorParameters 构造函数参数类型
在记录几个新学的内置类型,是基于对象操作 (映射类型),有对对象属性进行修饰操作的,(必选属性、可选属性、仅读的属性...)
partial / required / readonly 对对象属性进行修饰操作 Pick Omit 对象的结构操作1.Partial 转化可选属性 (?)
遍历所有的属性将属性设置为可选属性,默认只做了第一层处理,如果每个属性都需要设置,需要使用递归的方法
interface Company { name: string; num: number; } interface Person { name: string; age: number; company: Company; } type PartialPerson = Partial<Person>; // 内置的 type MyPartial<T> = { [K in keyof T]?: T[K]; }; type MyPartialPerson = MyPartial<Person>; // 自己实现的 // 深度转换 type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]; }; type MyDeepPartialPerson = DeepPartial<Person>; // 自己实现的 深度转换 // 验证,只写一部分必填参数,并不报错 let person: MyDeepPartialPerson = { name: "yya", company: { num: 10, }, };
2.Required 转化必填属性 (-?)
将所有的属性转化成必填属性,默认只做了第一层处理,如果每个属性都需要设置,需要使用递归的方法
interface Company { name?: string; num?: number; } interface Person { name?: string; age?: number; company: Company; } type RequiredPerson = Required<Person>; // 内置的 type MyRequired<T> = { [K in keyof T]-?: T[K]; }; type MyRequiredPerson = MyRequired<Person>; // 自己实现的 // 深度转换 type DeepRequired<T> = { [K in keyof T]-?: T[K] extends object ? DeepRequired<T[K]> : T[K]; }; type MyDeepRequiredPerson = DeepRequired<Person>; // 自己实现的 深度转换 // 验证, 可选属性不写,会报错 let person: MyDeepRequiredPerson = { name: "yya", company: { num: 10, }, };
3.Readonly 转化仅读属性 (readonly)
将所有属性变为仅读状态,默认只做了第一层处理,如果每个属性都需要设置,需要使用递归的方法
interface Company { name?: string; num?: number; } interface Person { name: string; age: number; company?: Company; } type ReadonlyPerson = Readonly<Person>; // 内置的 type MyReadonly<T> = { readonly [K in keyof T]: T[K]; }; type MyRequiredPerson = MyReadonly<Person>; // 自己实现的 // 深度转换 type DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K]; }; type MyDeepReadonlyPerson = DeepReadonly<Person>; // 自己实现的 深度转换 // 验证, 修改属性 报错 let person: MyDeepReadonlyPerson = { name: "yya", age: 18, }; person.name = "abc"; // 报错 无法分配到 "name" ,因为它是只读属性。
Mutate(非内置,与 Readonly 相对) (-readonly)
改变只读性
interface Company { readonly name: string; readonly num?: number; } interface Person { readonly name: string; readonly age: number; readonly company: Company; } type DeepMutate<T> = { -readonly [K in keyof T]: T[K] extends object ? DeepMutate<T[K]> : T[K]; }; type MyDeepMutatePerson = DeepMutate<Person>; // 自己实现的 深度转换 // 验证, 可以正常修改属性,且可以深度修改 let person: MyDeepMutatePerson = { name: "yya", age: 18, company: { name: "BJ", }, }; person.name = "abc"; person.company.name = "abc";
4.Pick 挑选所需的属性
在已有类型中挑选所需属性
interface Company { num: number; name: string; } interface Person { name: string; age: number; company: Company; } type PickPerson = Pick<Person, "name" | "age">; // 内置的 type myPick<T, K extends keyof T> = { [P in K]: T[P]; }; type myPickPerson = myPick<Person, "name" | "age">; // 自己实现的
5.Omit 忽略属性
忽略 xxx 属性 (先排除掉不需要的 key,在通过 key 选出需要的属性) 此处使用的 keyof any 进行限制,是因为可以忽略原类型中没有的属性 排出不需要的 key ,用到了之前介绍过的 Exclude 排除类型(差集) 方法interface Company { num: number; name: string; } interface Person { name: string; age: number; company: Company; } type OmitPerson = Omit<Person, "name" | "age">; // 内置的 // keyof any => number | string | symbol // type ex = Exclude<keyof Person, 'name'> // 借助集合的排出方法 剩余"age" | "company" type MyOmit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; // 自己实现的 type MyOmitPerson = MyOmit<Person, "name" | "age">;
查看更多关于TypeScript 学习笔记 — 基于对象操作的内置类型的使用(十二)的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did223140