← 전체 글로 돌아가기

TypeScript

TypeScript에서 날짜 타입이 자꾸 단언되어야 할 때

TypeScript에서 날짜 타입 관련 타입 에러가 반복될 때 확인해야 할 것들을 정리했다.

TypeScript 프로젝트를 하다 보면 날짜를 다루는 곳에서 타입 관련 에러가 자주 난다. as anyas unknown as Date 같은 타입 단언이 점점 늘어나는 경험을 한 적 있을 것이다. 이는 타입 정의 자체가 애매해서 생기는 문제다.

원본 데이터가 뭔지부터 확인

먼저 API에서 받아오는 실제 데이터를 본다.

# 테스트하려는 엔드포인트를 호출해서 응답을 본다
curl -i 'https://api.example.com/events' | jq '.data[0].createdAt'

응답이 다음 중 뭔지 확인:

  • "2024-06-28T10:30:00Z" (ISO 8601 문자열)
  • 1719574200000 (타임스탬프 밀리초)
  • 1719574200 (타임스탐프 초)
  • "2024-06-28" (날짜 문자열만)

API에서 뭔지 모르면 TypeScript가 자동으로 타입을 추론할 수 없다. 그래서 unknown 타입으로 왔다가, 우리가 Date로 단언해야 하는 상황이 반복되는 것이다.

타입 정의부터 명확히

API 응답 타입을 먼저 정의해야 한다.

// 실제로 오는 데이터 구조
interface EventResponse {
  id: string;
  createdAt: string; // ISO 8601 문자열로 온다면 string
  updatedAt: string;
}

// 앱에서 쓸 내부 타입
interface Event {
  id: string;
  createdAt: Date;
  updatedAt: Date;
}

그다음 변환 함수를 만든다:

function parseEvent(raw: EventResponse): Event {
  return {
    id: raw.id,
    createdAt: new Date(raw.createdAt),
    updatedAt: new Date(raw.updatedAt),
  };
}

이렇게 하면 API 응답이 들어오는 지점 한 곳에서만 타입을 변환하고, 나머지 코드에서는 타입 단언이 필요 없다.

문제가 여전히 반복된다면

타입 정의를 명확히 했는데도 자꾸 에러가 난다면:

# 타입 체크를 해본다
npm run build
npx tsc --noEmit

빌드 로그에서 정확히 어느 줄에서 문제가 나는지 본다. 보통 다음 중 하나다:

  1. null/undefined 가능성: createdAt: string | null로 와서 Date로 바로 못 만드는 경우
  2. 배열 처리: API에서 배열을 받을 때 타입을 배열로 정의하지 않은 경우
  3. 선택적 필드: createdAt?: string 같이 선택적인데, 코드에서 필수로 취급하는 경우

테스트해서 확인

타입 정의를 고쳤으면, 실제 API 응답으로 테스트한다:

// 테스트
const raw: EventResponse = { id: '123', createdAt: '2024-06-28T10:30:00Z', updatedAt: '2024-06-28T10:30:00Z' };
const event = parseEvent(raw);
console.log(event.createdAt instanceof Date); // true여야 함

TypeScript 에러가 더 이상 나지 않으면 타입 정의가 제대로 된 것이다. 이렇게 한 번 정리하면, 다음에 같은 문제가 나올 때는 같은 패턴으로 빠르게 처리할 수 있다.