kakasoo

달과 일자로 이루어진 MMDD 타입 본문

프로그래밍/TypeScript

달과 일자로 이루어진 MMDD 타입

카카수(kakasoo) 2024. 3. 17. 23:17
반응형

최초의 풀이와 오답

type Int = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0';
type February = '02'
type MonthsHasDays30 = '04' | '06' | '09' | '11';
type MonthsHasDays31 = '01' | '03' | '05' | '07' | '08' | '10' | '12';
type Months = February | MonthsHasDays30 | MonthsHasDays31;
type Days = Exclude<`${0 | 1 | 2}${Int}` | '30' | '31', '00'>

type DaysByMonth<T extends Months> = 
  T extends February 
    ? Exclude<Days, '29' | '30' | '31'> 
    : T extends MonthsHasDays30 
      ? Exclude<Days, '30'>
      : Days

type ValidDate<T extends string> = 
  T extends `${infer Month extends Months}${infer Days}` 
    ? Days extends DaysByMonth<Month>
      ? true
      : false
    : false;

 

31일로 이루어진 달들을 체크하고, 30일로 이루어진 달들을 체크한다.

2월은 윤년을 제외하면 28일까지만 있는 것이 일반적이기 때문에 달에 따라서 일자가 달라지게끔 DaysByMonth 타입을 정의한다.

DaysByMonth는 제네릭으로 받은 달(=Month) T에 따라 01부터 31까지 존재하는 Days에서 불가능한 날짜를 Exclude한다.

DaysByMonth가 완성되었다면 문제에서 구현하라고 하는 ValidDate 타입을 구현하면 된다.

ValidDate는 인자로 받은 제네릭 T를 Month와 Days로 구성되어 있는 문자열로 나누고 Days가 Month에 맞는지 검사한다.

문제는 나뉘어진 Month가, 예를 들어 '0101' 라면 '01' 일수도 있고 '10' 일 수도 있는 상황이 된다.

 

정답 풀이법

type Int = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0';
type February = '02'
type MonthsHasDays30 = '04' | '06' | '09' | '11';
type MonthsHasDays31 = '01' | '03' | '05' | '07' | '08' | '10' | '12';
type Months = February | MonthsHasDays30 | MonthsHasDays31;
type Days = Exclude<`${0 | 1 | 2}${Int}` | '30' | '31', '00'>

type Decimal = `${Int}${Int}`;

type DaysByMonth<T extends February | MonthsHasDays30 | MonthsHasDays31> = 
  T extends February 
    ? Exclude<Days, '29' | '30' | '31'> 
    : T extends MonthsHasDays30 
      ? Exclude<Days, '30'>
      : Days

type AllDays = {
  [M in Months]: `${M}${DaysByMonth<M>}`
}[Months]

type ValidDate<T extends string> = T extends AllDays ? true : false;

 

따라서 더 쉽게 풀기 위해서 일단 AllDays라는, '0101'부터 '1231'까지의 가능한 모든 날짜를 타입으로 만들고,

제네릭 인자 T가 그 날짜 중 하나인지를 검사하게 바꾼다.

반응형