logo hsb.horse
← スニペット一覧に戻る

Snippets

TypeScript Non-null アサーション

undefined や null を排除する TypeScript の型ガード関数。実行時エラーと型安全の両方を確保する。

公開日: 更新日:

外部 API や配列のインデックスアクセスでは、値が undefined になる可能性があり、型上はそのままだと扱いづらい。Non-null アサーションを使って、実行時チェックと型の絞り込みを両立させる。

コード

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 チェックを検討するべきだ。

実務メモ

このスニペットは、TypeScript の周辺で同じ操作や判定を毎回書きたくない時に向く。小さな補助として切り出しておくと、呼び出し側では意図だけを追いやすい。

逆に、分岐や前提条件が増えて責務が膨らむなら、1本のスニペットに詰め込まない方がよい。手順と helper を分けるか、役割ごとに切り出す方が保守しやすい。