logo hsb.horse
← 스니펫 목록으로 돌아가기

Snippets

TypeScript Non-null Assertion

undefined와 null을 제거하는 TypeScript 타입 가드 함수. 런타임 오류와 타입 안정성을 모두 보장한다.

게시일: 수정일:

외부 API나 배열 인덱스 접근에서는 값이 undefined가 될 가능성이 있어, 타입상 그대로는 다루기 어렵다. Non-null assertion을 사용해 런타임 체크와 타입 좁히기를 동시에 달성한다.

코드

function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
if (value === undefined || value === null) {
throw new Error(`Expected 'value' to be defined, but received ${value}`);
}
}
function nonNull<T>(value: T): NonNullable<T> {
assertIsDefined(value);
return value;
}

사용 예시

배열 요소 안전하게 가져오기

const arr = [1, 2, 3];
const value = arr[10]; // number | undefined
// 타입 에러를 피할 수 없음
console.log(value.toFixed()); // Error: Object is possibly 'undefined'
// nonNull 사용
const safeValue = nonNull(arr[10]);
// NonNullable<number>로 추론됨
console.log(safeValue.toFixed()); // OK

API 응답 검증

interface User {
name: string;
}
async function getUser(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
const user = await response.json() as User | undefined;
// 응답이 비어있으면 에러
assertIsDefined(user);
// 이 시점에서 user는 User 타입으로 다룰 수 있음
return user;
}

! 연산자와의 차이

TypeScript에는 value!라는 non-null assertion 연산자도 있지만, 이는 런타임 체크를 수행하지 않는다. assertion 함수를 사용하면 런타임에 값을 검증하면서 타입도 좁힐 수 있다.

주의사항

assertion 함수는 값이 정말로 존재한다고 확신할 수 있는 경우에 사용한다. 무턱대고 사용하면 런타임 에러가 발생한다. 특히 배열의 인덱스 접근에서는 미리 length 체크를 고려해야 한다.