이 글은 제가 타입챌린지를 하면서 해석한 내용을 적는 글입니다. 틀린 내용이 있으면 댓글 달아주시면 감사하겠습니다.
https://github.com/type-challenges/type-challenges/blob/main/questions/00645-medium-diff/README.md
제네릭 O와 O1를 인자로 받아, 두 객체의 공통된 속성을 제외한 나머지 속성을 리턴하는 타입이다.
잘 모르겠다면, 다음 챌린지를 참고하자.
https://suloth.tistory.com/73?category=1092932
위의 포스팅을 보았다면, 이 문제가 생각보다 쉽게 느껴질 것이다.
// 1번째 답
type Diff<O, O1> = {
[P in keyof O | keyof O1 as P extends keyof (O | O1) ? never : P]:
P extends keyof O ? O[P] : P extends keyof O1 ? O1[P] : never;
}
// 2번째 답
type Diff<O, O1> = {
[P in keyof (O & O1) as P extends keyof (O | O1) ? never : P]: (O & O1)[P]
}
/* _____________ Test Cases _____________ */
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 }>>,
]
1번째 답은... 2번째 답의 열화 버전이니 2번째 답만 해설하겠다.
[P in keyof (O & O1) as P extends keyof (O | O1) ? never : P] : (O & O1)은 O와 O1의 속성 모두를 가지고 있는 타입이다. 따라서 해당 타입의 key값을 P라고 한다. 그런데, P가 (O | O1)의 키이면, never를 리턴하여 key값을 리턴하지 않고, 만약 아니라면 P를 리턴하여 키 값을 나오게한다. 여기서 (O | O1)은 O와 O1 속성의 공통된 속성만을 가지므로 겹치는 속성을 제외할 수 있다.
(O & O1)[P] : 그리고 key값들의 타입은 (O & O1)타입에 있을테니, (O & O1)[P] 로 지정해준다.
keyof (O | O1) 대신, keyof O & keyof O1 과 같이 문자열을 연산하여 사용하여도 됩니다. 자세한 설명은 위의 Merge 포스팅에 맨아래 부분에 나와있습니다.
type Diff<O, O1> = {
[P in keyof (O & O1) as P extends keyof O & keyof O1 ? never : P]: (O & O1)[P]
}
'Language > Typescript' 카테고리의 다른 글
타입챌린지 : 1042-IsNever (medium) (0) | 2023.04.19 |
---|---|
타입챌린지 : 949-AnyOf (medium) (0) | 2023.04.18 |
타입챌린지 : 612-KebabCase (medium) (0) | 2023.04.16 |
타입챌린지 : 599-Merge (medium) (2) | 2023.04.15 |
타입챌린지 : 531-String to Union (medium) (0) | 2023.04.11 |