rimo030 / type-challenges

Collection of TypeScript type challenges with online judge
https://tsch.js.org/
MIT License
3 stars 0 forks source link

no - 645 Diff #101

Open rimo030 opened 6 months ago

rimo030 commented 6 months ago
type Diff<O, O1> = Omit<O & O1, keyof (O | O1)>
import type { Equal, Expect } from '@type-challenges/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 }>>,
]
rimo030 commented 6 months ago

처음에는 아래와 같이 작성했었는데, 간결한 솔루션이 있어서 놀랐다.

  1. 서로에게 존재하는 프로퍼티를 삭제한 후 인터섹션 합니다.

    type Diff<O, O1> = Omit<{
    [K in keyof O as K extends keyof O1 ? never : K] : O[K];
    } & {
    [K in keyof O1 as K extends keyof O ? never : K] : O1[K];
    }, never>
  2. 따라서 아래와 같습니다.

    type Diff<O, O1> = Omit<Omit<O, keyof O1> & Omit<O1, keyof O>, never>
  3. 따라서 아래와 같습니다.

    type Diff<O, O1> = Omit<O & O1, keyof (O | O1)>