타입 챌린지 472 - Tuple to Enum Object

소파의 벨로그·2025년 7월 7일

타입챌린지

목록 보기
129/131

문제 링크

문제

enum은 타입스크립트의 기본 문법이다(자바스크립트에는 존재하지 않는다).
이 질문에서 타입은 문자열 튜플을 enum처럼 동작하는 객체로 바꿔야 한다.

게다가, 이넘의 속성은 파스칼 케이스가 선호된다.

만약 두 번째 인자가 true라면 값은 숫자 리터럴이여야 한다.

The enum is an original syntax of TypeScript (it does not exist in JavaScript).

In this question, the type should convert a given string tuple to an object that behaves like an enum.
Moreover, the property of an enum is preferably a pascal case.

If true is given in the second argument, the value should be a number literal.

내 풀이


type EnumNumber<T extends readonly string[],Index extends any[]=[]>=
  Index['length'] extends T['length']?{}:
  {
    readonly [R in T[number] as Capitalize<R>]:T[Index['length']] extends R?Index['length']:Capitalize<R> extends keyof EnumNumber<T,[...Index,1]>?EnumNumber<T,[...Index,1]>[Capitalize<R>]:never;
  }

type Enum<T extends readonly string[], N extends boolean = false> =
  N extends true?EnumNumber<T>:
 {
  readonly [R in T[number] as Capitalize<R>]:R
}

만약 두 번째 인자가 false라면 튜플의 모든 타입을 Capitalize된 타입을 키로, 원래 타입을 value로 가지는 객체를 반환한다. 이때 모든 타입은 readonly이다.

만약 두 번째 인자가 true라면, 다음과 같은 과정을 거친다.

키 타입은 기존처럼 튜플의 모든 타입을 Capitalize된 타입으로 가진다.
재귀적으로 동작하며, 매 재귀의 타입은 인덱스 별로 다음과 같이 반환된다.

// ['a','b','c']에서 인덱스가 0인 경우
{
	A:0,
    ['B'|'C']:그 뒤의 재귀 타입['B'|'C']
}

// ['a','b','c']에서 인덱스가 1인 경우
{
	B:1,
    ['C']:그 뒤의 재귀 타입['C']
}

// ['a','b','c']에서 인덱스가 2인 경우
{
	'C':2
}

이런 식으로 재귀적으로 동작하여 최종적으로는 숫자형태의 Enum을 반환한다.

0개의 댓글