1. 先定义一个Person类型
interface PersonProps {
name: string;
age?: number;
email?: string;
}
2. 写一个排除必填项的类型
type PartialPropsOnly<T> = {
// 如果 T 是 Record<K, T[K]> 的超集,则是必填项,为never,在新的TS类型中就去掉了这个选项
[K in keyof T as T extends Record<K, T[K]> ? never : K]: T[K];
};
type PartialProps = PartialPropsOnly<PersonProps>;
// 结果可以看出,PartialProps 是OK的
// { age?: number; email?: string; }
3. 尝试增加第二个参数,true/false
type FilterPropsIsRequired<T, S extends boolean> = {
[K in keyof T as T extends Record<K, T[K]>
? S extends true
? K
: never
: S extends true
? never
: K]: T[K];
};
4. 将FilterPropsIsRequired再次整合
type FilterPartial<T> = FilterPropsIsRequired<T, false>;
type FilterRequired<T> = FilterPropsIsRequired<T, true>;
type RequiredProps = FilterPartial<PersonProps>;
// { name: string; }
type PartialProps = FilterRequired<PersonProps>;
// { age?: number; email?: string; }
至此,我们就完成了在TS属性排除必填项/非必填项的功能。