TypeScript 5.5의 Inferred Type Predicates 도입 후기
문제 상황
프로젝트에서 배열 필터링 시 타입 가드를 자주 사용하는데, 매번 반환 타입을 is 키워드로 명시하는 게 번거로웠다.
// 기존 방식
function isNotNull<T>(value: T | null): value is T {
return value !== null;
}
const values = [1, null, 2, null, 3];
const filtered = values.filter(isNotNull); // number[]
반환 타입을 명시하지 않으면 타입이 좁혀지지 않아 (number | null)[]로 남았다.
TypeScript 5.5 적용
5.5로 업데이트 후 명시적 type predicate 없이도 타입 추론이 작동했다.
// 5.5 이후
function isNotNull<T>(value: T | null) {
return value !== null;
}
const filtered = values.filter(isNotNull); // number[]
컴파일러가 함수 본문을 분석해 자동으로 type predicate를 추론한다.
적용 범위
단순 null/undefined 체크뿐 아니라 프로퍼티 존재 여부 확인에도 적용됐다.
interface User {
id: string;
email?: string;
}
function hasEmail(user: User) {
return user.email !== undefined;
}
const users: User[] = [...];
const withEmail = users.filter(hasEmail);
// { id: string; email: string }[]
주의사항
복잡한 로직에서는 여전히 명시적 type predicate가 필요했다. 추론이 실패하는 경우 기존 방식으로 작성하면 된다.
레거시 코드의 기존 type predicate는 호환되므로 점진적 마이그레이션이 가능하다.