Typescript 类型体操
|
和 &
的区别
经过实验
IProps1 & IProps2
: 取并集
IProps1 | IProps2
= Partical<IProps1 & IProps2>
实现真正的「或」逻辑
我们会发现,编写类型时使用的 |
并不是我们理解的或
如
interface IProps1 { firstName: string lastName: string } interface IProps2 { fullName: string } type IPerson = IProps1 | IProps2 期望:ts报错 实际:通过ts校验 const p1 = { firstName: 'jenson', lastName: 'liu', fullName: 'jensonliu' } 复制代码
我也不知道这是设计失误还是设计本意,如果想模拟出真正的或
逻辑,还是需要一点黑科技的。
思路
使用never
类型
interface IProps1 { firstName: string lastName: string fullName?: never } interface IProps2 { firstName?: never lastName?: never fullName: string } type IPerson = IProps1 | IProps2 复制代码
这就是手动告诉编译器,fullName
存在时firstName
和lastName
都为never,反之亦然
改进
当然,我们不能对每个interface都去手动写never,因此可以抽取成通用的类型方法
type ExcludeToNever<T, V> = { [P in keyof Omit<V, keyof T>]?: never; // V中存在而T中不存在的属性 } & { [P in keyof T]: T[P]; // T的原有属性 }; 复制代码
ExcludeToNever传入两个interface,即T和V, 将V中存在而T中不存在的属性设置为never并塞入T中
然后
type IOr<F, S> = ExcludeToNever<F, S> | ExcludeToNever<S, F> 复制代码
这样一来就将两个interface中彼此不存在的key都用never填充了
作者:一个大冰球
链接:https://juejin.cn/post/7016627699414204447