bkdragon's log

Deep Readonly 본문

Typescript

Deep Readonly

bkdragon 2023. 3. 10. 13:08

타입챌린지 Deep Readonly를 풀고 든 생각을 정리해보려 한다. 아래는 문제의 링크이다.

 

https://github.com/type-challenges/type-challenges/blob/main/questions/00009-medium-deep-readonly/README.ko.md

 

GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge

Collection of TypeScript type challenges with online judge - GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge

github.com

문제를 보고 바로 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]>
}

 

최종 형태이다. 

 

'Typescript' 카테고리의 다른 글

Template Literal Types  (0) 2023.04.04
Conditional types  (0) 2023.03.22
Chainable Options  (0) 2023.03.14
key in keyof T as key extends K ? never : key ???  (0) 2023.03.03
T[number] 란?  (0) 2023.03.02