← 전체 글로 돌아가기

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 처리를 해야 한다.