外部 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()); // OKAPI レスポンスの検証
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 チェックを検討するべきだ。
hsb.horse