Diff
挑战
获取两个接口类型中的差值属性。
例如:
type Foo = {
name: string;
age: string;
};
type Bar = {
name: string;
age: string;
gender: number;
};
type test0 = Diff<Foo, Bar>; // expected { gender: number }
解答
这个挑战要求我们基于对象进行操作。所以有极大可能,映射类型可以发挥作用。
让我们从映射类型开始,在这里我们迭代两个对象的属性联合(union)。毕竟在计算差值 之前,我们需要收集两个对象的所有属性。
type Diff<O, O1> = { [P in keyof O | keyof O1]: never };
当我们遍历这些属性的时候,我们需要检查这个属性是否存在于O
或者 O1
。所以我们
在这里需要添加一个条件类型来找出我们需要从哪里获取值类型。
type Diff<O, O1> = {
[P in keyof O | keyof O1]: P extends keyof O
? O[P]
: P extends keyof O1
? O1[P]
: never;
};
太棒了!我们得到了一个对象,它是两个对象所有属性的联合。剩下的最后一件事是过滤掉 那些在两个对象上都存在的属性。
我们如何获得两个对象上存在的所有属性呢?交叉类型!我们先获取交叉类型,然后把它从
我们的映射类型P
中剔除
type Diff<O, O1> = {
[P in keyof O | keyof O1 as Exclude<P, keyof O & keyof O1>]: P extends keyof O
? O[P]
: P extends keyof O1
? O1[P]
: never;
};
评论