type-challenges:Diff

48 阅读1分钟

Diff

问题描述

获取两个接口类型中的差值属性。

type Foo = {
  a: string;
  b: number;
}
type Bar = {
  a: string;
  c: boolean
}
​
type Result1 = Diff<Foo,Bar> // { b: number, c: boolean }
type Result2 = Diff<Bar,Foo> // { b: number, c: boolean }
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'type Foo = {
  name: string
  age: string
}
type Bar = {
  name: string
  age: string
  gender: number
}
type Coo = {
  name: string
  gender: number
}
​
type cases = [
  Expect<Equal<Diff<Foo, Bar>, { gender: number }>>,
  Expect<Equal<Diff<Bar, Foo>, { gender: number }>>,
  Expect<Equal<Diff<Foo, Coo>, { age: string; gender: number }>>,
  Expect<Equal<Diff<Coo, Foo>, { age: string; gender: number }>>,
]
​
​
// ============= Your Code Here =============
// 答案1
// type Diff<O extends {}, O1 extends {}> ={
//   [P in Exclude<(keyof O | keyof O1), keyof(O | O1)>]:(O & O1)[P] 
// }// 答案2
type Diff<O extends {}, O1 extends {}> = {
  [K in Exclude<keyof (O & O1), keyof(O | O1)>]: (O & O1)[K]
}
​

解释: 在对象中使用交、并集

在对象中使用 |&,与在非对象中使用存在语义上的差异。

在集合对象中使用联合类型 | ,官网 working-with-union-types 有如下说明:

Notice that given two sets with corresponding facts about each set, only the intersection of those facts applies to the union of the sets themselves.

type Foo = {
  name: string
  age: string
}
type Bar = {
  name: string
  age: string
  gender: number
}
​
type result = keyof (Foo | Bar) // "name" | "age"

在集合对象中使用交集类型 & ,可以见 intersection-types 给出的 demo:

interface Colorful {
  color: string;
}
interface Circle {
  radius: number;
}
​
type ColorfulCircle = keyof (Colorful & Circle) // "color" | "radius"

结合 &| 的使用,我们能立马写出比如类型 diff