TypeScript
TypeScript optional 타입 에러 원인 찾기
optional 값 처리에서 타입 에러가 발생할 때 빌드를 실패시키지 않고 체계적으로 원인을 좁혀가는 방법.
TypeScript에서 optional 타입 에러는 빌드를 멈춘다. "Type 'string | undefined' is not assignable to type 'string'" 같은 메시지를 보면 짜증난다. 하지만 차분히 접근하면 패턴을 찾을 수 있다.
에러 메시지 정확히 읽기
TypeScript 컴파일 에러는 정확하다. 파일 경로와 줄 번호를 적어둔다.
npm run build
# Error: src/pages/api/user.ts(45,10): Type 'User | undefined' is not assignable...
그 줄의 코드를 본다. 무엇이 undefined일 수 있는데, 함수가 undefined를 허용하지 않는 상황인가?
타입 가드 추가
가장 흔한 해결은 null 체크다:
// 에러 발생
const name: string = user.name; // user가 undefined일 수 있음
// 수정
if (!user) return null;
const name: string = user.name; // 이제 안전
optional 체이닝(?.)도 자주 쓰인다:
const name = user?.name ?? 'Unknown';
Union 타입 정확히 선언
함수가 undefined를 반환할 수 있다면 타입에 명시한다:
// 잘못된 선언
function getUser(id: string): User {
if (!id) return undefined; // 에러
}
// 올바른 선언
function getUser(id: string): User | undefined {
if (!id) return undefined; // OK
}
호출자는 undefined를 처리해야 한다.
타입 추론 vs 명시
때로는 TypeScript가 타입을 잘못 추론한다. 명시적으로 선언하면 도움이 된다:
// 자동 추론 (실수할 수 있음)
const items = Array.from(data.map(x => x.value));
// 명시적 선언 (명확함)
const items: (string | undefined)[] = data.map(x => x.value);
명시적으로 선언하면 어떤 타입이 nullable인지 바로 보인다.
라이브러리 타입 확인
외부 라이브러리를 사용할 때, 반환 타입이 optional인지 확인한다:
// 라이브러리의 타입 정의
function query(sql: string): Row[] | undefined
// 사용할 때 처리 필요
const rows = query(sql);
if (rows) {
rows.forEach(...);
}
TypeScript 버전이나 타입 정의 버전이 업데이트되면서 타입이 바뀔 수도 있다.
strict 모드 고려
프로젝트의 tsconfig.json에서 strictNullChecks가 활성화되어 있나?
{
"compilerOptions": {
"strictNullChecks": true
}
}
이 설정이 켜져 있으면 모든 optional 값을 체크해야 한다. strict 모드는 초기에는 번거롭지만, 버그를 사전에 방지한다.
빠른 임시 해결
급할 땐 non-null assertion operator (!)를 쓸 수 있다:
const name: string = user!.name; // user가 null이 아니라고 강제
하지만 이것은 임시 방편이다. 실제로는 타입을 정확히 선언하고 null 처리를 해야 한다.