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이라는 에러가 나온다면, 어디서 타입 정보가 사라졌는가?
한 가지씩 타입 명시하기
한 번에 모든 타입을 고치려 하지 말 것. 가장 기본적인 부분부터 타입을 명시하고, 빌드해본다. 에러가 줄었는가? 그럼 그 방향이 맞다.
결과를 검증하기
타입 에러가 모두 사라졌으면, 실제로 코드가 정상적으로 작동하는가? 런타임에 예상치 못한 에러는 없는가?
타입 에러를 푸는 것보다 중요한 건, 왜 그 타입을 정의했는지 이해하는 것이다. 안전한 타입 설계는 미래의 버그를 방지하는 최선의 방법이다.