← 전체 글로 돌아가기

TypeScript

TypeScript optional 타입을 안전하게 다루기

TypeScript에서 optional 값을 다룰 때 생기는 실수들과 그 해결책을 정리했다.

Optional이 뭐가 어렵나 싶었는데

TypeScript는 ?로 optional을 표현한다. 하지만 이게 생각보다 까다롭다.

interface User {
  name: string;
  email?: string;
}

email은 있을 수도, 없을 수도 있다. 여기까진 간단해 보인다.

문제는 사용할 때다

optional 값을 사용할 때:

function printEmail(user: User) {
  console.log(user.email.toLowerCase());
  // Error: Object is possibly 'undefined'
}

TypeScript가 경고한다. email이 없을 수도 있으니 바로 method를 쓸 수 없다는 뜻이다.

안전한 방법들

1. Type guard로 체크하기

function printEmail(user: User) {
  if (user.email) {
    console.log(user.email.toLowerCase());
  }
}

가장 명확한 방법이다.

2. Optional chaining 사용하기

function printEmail(user: User) {
  console.log(user.email?.toLowerCase());
}

?.는 존재할 때만 method를 실행한다.

3. Nullish coalescing으로 기본값 제공하기

function printEmail(user: User) {
  console.log(user.email?.toLowerCase() ?? "no email");
}

??는 null/undefined일 때만 우측 값을 사용한다.

배열의 optional

배열도 optional일 수 있다:

interface Post {
  tags?: string[];
}

const post: Post = {};
post.tags?.forEach(tag => console.log(tag));

실수하기 쉬운 부분

optional인 줄 알았는데 아니거나, 아닌 줄 알았는데 optional인 경우가 많다.

interface Response {
  data: { id: number } | null;
}

const res: Response = { data: null };
console.log(res.data.id);
// Error: Object is possibly 'null'

data는 required이지만 null일 수 있다. 이건 optional과는 다르다.

nullable 타입인지, optional 속성인지 구분해야 한다.