TypeScript 3.8 도입하며 겪은 타입 에러 해결기

배경

재택근무가 시작되면서 팀 내 코드 품질 개선 작업을 진행하게 되었다. TypeScript 3.8로 업그레이드하면서 기존에 any로 처리했던 부분들을 제대로 타이핑하기로 했다.

주요 이슈

1. Optional Chaining 도입

3.8의 핵심 기능인 optional chaining을 활용해 기존 코드를 리팩토링했다.

// Before
const userName = user && user.profile && user.profile.name;

// After
const userName = user?.profile?.name;

훨씬 간결해졌고, null/undefined 체크 로직이 명확해졌다.

2. API 응답 타입 정의

가장 시간이 오래 걸린 부분이었다. 백엔드 API 응답을 제대로 타이핑하지 않아서 런타임 에러가 자주 발생했다.

interface ApiResponse<T> {
  data: T | null;
  error?: {
    code: string;
    message: string;
  };
}

interface User {
  id: number;
  email: string;
  profile: {
    name: string;
    avatar?: string;
  };
}

const fetchUser = async (id: number): Promise<ApiResponse<User>> => {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
};

3. Utility Types 활용

Partial, Pick, Omit 등을 적극 활용해 중복 타입 정의를 줄였다.

type UserUpdatePayload = Partial<Omit<User, 'id'>>;

결과

  • 타입 관련 런타임 에러 70% 감소
  • IDE 자동완성으로 개발 속도 향상
  • 리팩토링 시 안정성 확보

초기 타이핑 작업은 번거로웠지만, 장기적으로는 확실히 투자 가치가 있었다.