在日常工作中,有时为了满足特殊的需求,需要定制一些自定义工具类型,以达到提高工作效率及简化代码的目的。本篇文章将记录几种自定义工具类型的使用及实现,以便学习。
更多自定义工具可以参考 utility-types
提示:以下是本篇文章正文内容,下面案例可供参考
namespace a {
type Proxy<T> = {
get(): T,
set(value: T): void
}
type Proxity<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxity<T>(obj: T): Proxity<T> {
let result = <Proxity<T>>{};
for (const key in obj) {
Object.defineProperty(result, key, {
enumerable: true,
configurable: true,
get: () => {
return obj[key];
},
set: (value) => {
obj[key] = value;
}
})
}
return result;
}
interface Props {
name: string,
age: number
}
let obj: Props = {
name: '张三',
age: 10
}
obj.name = '李四'
let res = proxity<Props>(obj);
console.log(res); // { name: [Getter/Setter], age: [Getter/Setter] }
}
namespace a {
type Proxy<T> = {
get(): T,
set(value: T): void
}
type Proxity<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function unProxity<T>(t: Proxity<T>): T {
let result: any = {} as T;
for (const key in t) {
result[key] = t[key];
}
return result;
}
let ret = unProxity<Props>(res);
console.log(ret); // { name: '李四', age: 10 }
}
namespace b {
type SetDifference<T, U> = T extends U ? never : T;
type A = string | number | symbol;
type B = number | boolean;
type AB = SetDifference<A, B>; // type AB = string | symbol
}
namespace c {
type SetDifference<T, U> = T extends U ? never : T;
type Omit<T, K extends keyof any> = Pick<T, SetDifference<keyof T, K>>;
type Person = { name: string, age: number, isMan: boolean };
type OmitAgePerson = Omit<Person, 'age' | 'name'>; // { isMan: boolean; }
}
namespace d {
type Props = { name: string, age: number, isMan: boolean };
type DefaultProps = { age: number };
type SetDifference<T, U> = T extends U ? never : T;
type Diff<T extends object, U extends object> = Pick<T, SetDifference<keyof T, keyof U>>;
type DiffProps = Diff<Props, DefaultProps>; // { name: string, isMan: boolean; }
}
namespace e {
// 注意:下面这三种写法都可以
// Extract & Extract
// Extract
// Extract
type InterSection<T extends object, U extends object> = Pick<T, Extract<keyof T, keyof U> & Extract<keyof U, keyof T>>;
type Props = { name: string, age: number, isMan: boolean };
type DefaultProps = { age: number };
type DuplicateProps = InterSection<Props, DefaultProps>; // { age: number }
}
namespace f {
type OldProps = { name: string, age: number, isMan: boolean };
type NewProps = { name: number, sex: string };
// SetDifference 找出 T 中有,但 U 中没有的属性
type SetDifference<T, U> = T extends U ? never : T;
// Diff 找出 T 中有,但 U 中没有的属性
type Diff<T extends object, U extends object> = Pick<T, SetDifference<keyof T, keyof U>>;
// InterSection 找出 T 和 U 中都有的属性
type InterSection<T extends object, U extends object> = Pick<T, Extract<keyof T, keyof U> & Extract<keyof U, keyof T>>;
type OverWrite<
T extends object,
U extends object,
// Diff 是:{ age: number, isMan: boolean }
// InterSection 是:{ name:number }
// 所以 I 就是:{ name:number, age: number, isMan: boolean }
// 如果也想返回 sex 属性,那么此处需要改写成 I = Diff & U
I = Diff<T, U> & InterSection<U, T>
> = Pick<I, keyof I>;
type ReplaceProps = OverWrite<OldProps, NewProps>; // { name: number, age: number, isMan: boolean };
}
namespace g {
type Obj1 = {
id: number,
name: string
}
type Obj2 = {
id: number,
age: number
}
type Compute<T extends any> = T extends Function ? T : { [K in keyof T]: T[K] };
type SetDifference<T, U> = T extends U ? never : T;
type Omit<T, K extends keyof any> = Pick<T, SetDifference<keyof T, K>>;
type Merge<T extends object, U extends object> = Compute<Obj1 & Omit<Obj2, keyof Obj1>>;
type obj = Merge<Obj1, Obj2>;
/**
type obj = {
id: number;
name: string;
age: number;
}
*/
}
本篇文章主要记录了ts中的一些自定义工具类型,下次再见。