← 전체 글로 돌아가기

TypeScript

TypeScript 설정 객체를 다룰 때 타입 에러 좁혀나가기

optional 필드, null 체크, 타입 가드를 단계적으로 정의해서 설정 객체의 타입을 명확하게 만드는 방법.

TypeScript로 설정 객체를 다루다 보면 복잡한 타입 에러에 빠진다. 어떤 필드는 optional이고, 어떤 필드는 null일 수 있고, 어떤 필드는 반드시 있어야 한다. 이 모든 걸 타입으로 표현하는 건 생각보다 까다롭다.

먼저 타입 정의를 명확히 하기

npm run build
npx tsc --noEmit

에러가 어디서 나는가? 정확한 파일과 줄 번호를 찾자.

타입 정의부터 정확히

설정 객체의 타입을 최대한 구체적으로 정의한다.

interface Config {
  name: string;              // 필수
  port?: number;             // optional
  debug: boolean | null;     // boolean이거나 null
}

optional인 필드에는 ?를 붙이고, null을 허용하려면 | null을 추가한다.

Optional과 null을 구분하기

name?: string은 필드 자체가 없을 수도 있다는 뜻이다. 반면 name: string | null은 필드는 있지만 값이 null일 수 있다는 뜻이다.

이 둘은 다르다. 타입 정의를 명확히 해야 나중에 런타임 에러를 피할 수 있다.

타입 가드로 안전하게 처리하기

if (config.port !== undefined && config.port > 0) {
  console.log(`Running on port ${config.port}`);
}

TypeScript는 이 조건을 만족하면 config.port의 타입을 number로 좁혀준다.

빌드 에러 제거하기

npm run build

빌드가 실패하는 부분의 타입을 정확히 읽자. Expected string, got unknown이라는 에러가 나온다면, 어디서 타입 정보가 사라졌는가?

한 가지씩 타입 명시하기

한 번에 모든 타입을 고치려 하지 말 것. 가장 기본적인 부분부터 타입을 명시하고, 빌드해본다. 에러가 줄었는가? 그럼 그 방향이 맞다.

결과를 검증하기

타입 에러가 모두 사라졌으면, 실제로 코드가 정상적으로 작동하는가? 런타임에 예상치 못한 에러는 없는가?

타입 에러를 푸는 것보다 중요한 건, 왜 그 타입을 정의했는지 이해하는 것이다. 안전한 타입 설계는 미래의 버그를 방지하는 최선의 방법이다.