微软官是通过Pick 和exclude组合来实现Omit逻辑的,我们可以通过以下的代码实现同样的功能。
type MyOmit<T, K> = { [P in keyof T as P extends K ? never : P]: T[P] };type P5 = MyOmit<erson, 'id' | 'name'> // {age: number;}
代码中的as P extends K ? never : P这部分代码叫做重映射 ,由于我们不肯定必要的是P,有些环境下必要对P举行一些转换;案例中K 中包含的P键值范例则通过never忽略了,相反则生存。所以末了的效果是{age: number;}
给对象范例添加新的属性
type AppendToObject<T, U extends keyof any, V> = {[P in keyof T | U]: P extends keyof T ? T[P] : V}type P6 = AppendToObject<erson, 'address', string> // { address: string; id: number; name: string; age: number; }和条件范例组合实现功能
两个对象范例归并成一个新的范例
type Merge<F extends Record<string, any>, S extends Record<string, any>> = { [P in keyof F | keyof S]: P extends keyof S ? S[P] : P extends keyof F ? F[P] : never;};type Skill = { run: () => void;}type P7 = Merge<erson, Skill>; // { id: number; name: string; age: number; run: () => void; }
案例中P extends keyof S ? X : Y 的部分叫做 条件范例(背面也会单独先容)。代码中的含义就是假如 P是F的属性范例,则取F[P],假如P是S的属性范例,则取S[P]。
小结
颠末前面的先容,应该对keyof的利用有一些感觉了。下面我列一些代码,各人可以感受下:
type _DeepPartial<T> = { [K in keyof T]?: _DeepPartial<T[K]> }type Diff<T extends Record<string, any>, U extends Record<string, any>> = { [P in keyof U | keyof T as P extends keyof U ? P extends keyof T ? never : P : P extends keyof T ? P : never]: P extends keyof U ? U[P] : P extends keyof T ? T[P] : never;};