Typescript
Deep Readonly
bkdragon
2023. 3. 10. 13:08
타입챌린지 Deep Readonly를 풀고 든 생각을 정리해보려 한다. 아래는 문제의 링크이다.
문제를 보고 바로 extends(conditional types)를 이용해 분기처리 해야함을 생각할 수 있다.
처음 나의 풀이는 이러하다.
type DeepReadonly<T> = {
readonly [key in keyof T] : T[key] extends Record<string, any>
? ( T[key] extends Function ? T[key] : DeepReadonly<T[key]> )
: T[key]
}
내부의 값이 객체이면 재귀해주는 형태이다. 이 풀이는 유독 복잡해보이는데 그 이유는 Function이 Record로 걸러지지 않기 때문에 한번더 분기처리를 해줘야 하기 때문이다.
그렇다면!
반대로 생각해보는 것은 어떨까? 문제에 집중해서 내부의 값이 객체라는것에 그동안 집중해왔지만 역으로 객체가 아니라는 것에 초점을 맞추면 더 쉽게 해결 할 수 있을 수도 있다. 그렇게해서 수정한 풀이는 다음과 같다.
type DeepReadonly<T> = {
readonly [key in keyof T] : T[key] extends string | number | Function | boolean ? T[key] : DeepReadonly<T[key]>
}
유니온 타입을 이용했다. 조금 더 간단해졌지만 오류가 발생할 여지가 있는 풀이이다.
좀 더 업그레이드 해서 객체라면 키 값이 있을것이다. 그 키값이 없다면? 객체가 아니라는 말이 된다.
type DeepReadonly<T> = {
readonly [key in keyof T] : keyof T[key] extends never ? T[key] : DeepReadonly<T[key]>
}
최종 형태이다.