이 글은 제가 타입챌린지를 하면서 해석한 내용을 적는 글입니다. 틀린 내용이 있으면 댓글 달아주시면 감사하겠습니다.
PartialByKeys와는 반대로, K라는 이름을 가진 optional인 속성을 required로 바꾸어서 리턴하는 타입이다.
처음에 생각한 답
type IntersectionToObj<T> = {
[P in keyof T]: T[P]
}
type RequiredByKeys<T, K extends keyof T> = IntersectionToObj<{
K: T[K]
} & {
[P in keyof T as P extends K ? never : P]: T[P]
}>
인터섹션타입을 obj로 바꾸는 타입인 IntersectionToObj를 이용해서 K만 따로 객체로 만들고, 키 값이 K인 것을 제외한 나머지는 그대로 optional로 해서 리턴하는 타입을 만들었다.
하지만, 결과가 key값: string 이런식으로 나와야하는데, 계속 K: string | undefined 이런식으로 나와서 에러가 떴다.
그리고 자꾸 쓸데없이 value타입 뒤에 undefined가 붙는다... 이게 왜 붙는지 모르겠다.
type RequiredByKeys<T, K extends keyof T> = T[K] extends undefined | infer F ? IntersectionToObj<{
[P in K]: F
} & {
[P in keyof T as P extends K ? never : P]: T[P]
}> : never
이것은 두 번째 답이다. (오답)
T[K]가 undefined를 상속한다면 undefined를 제외한 F를 리턴하도록 만들어봤는데... K에 유니온타입이 들어가면, F에도 똑같이 유니온 타입이 들어가버린다 ㅋㅋ
결국.. 이것저것 시도해봤는데 잘 되지 않아서 다른 분들의 답을 보았다....
type RequiredByKeys<T , K extends keyof T = keyof T> = Omit<
T & Required<Pick<T,K & keyof T>>, never>
Omit을 이용해 Intersection을 객체로 바꾸어주고,
Pick<T, K & keyof T> : T에서 키 값 K를 가진 속성만 뽑아서 (A)
T & Required<A> : 뽑은 속성을 Required로 바꾸어주고 T와 Intersection을 한다.
또 다른 답이다.
type RequiredByKeys<T, K extends keyof T = keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
} & {
[P in keyof T as P extends K ? P : never]-?: T[P]
} extends infer I
? { [P in keyof I]: I[P] }
: never
해당 코드를 통해 두 가지를 알 수 있었다.
첫 째는 [P]-?: T[P] 를 통해 optional(partial)을 해제할 수 있다는 것이었고,
둘 째는 {intersection type} extends infer I ? { [P in keyof I]: I[P] } 를 통해 intersection type을 obj로 바꿀 수 있다는 점이었다.
'Language > Typescript' 카테고리의 다른 글
타입챌린지 : 2852-OmitByType (medium) (0) | 2023.05.20 |
---|---|
타입챌린지 : 2793-Mutable (medium) (0) | 2023.05.18 |
타입챌린지 : 2757-PartialByKeys (medium) (0) | 2023.05.11 |
타입챌린지 : 2693-EndsWith (medium) (0) | 2023.05.09 |
타입챌린지 : 2688-StartsWith (medium) (0) | 2023.05.08 |