0Pricing
TypeScript Academy · レッスン

Non-nullアサーション演算子

!演算子を使い、値がnullでもundefinedでもないことをアサートします。

「Non-nullアサーション演算子」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

非 null アサーション演算子

後置!演算子は、ここでは値がnullまたはundefinedではないと TypeScript に伝えます。実行時のチェックなしに、それらを型から取り除きます。

function firstChar(s: string | null): string {
  return s!.charAt(0); // assert s is not null
}
console.log(firstChar('hello'));

! を置く場所

!は、アサーション対象の式の直後、さらにアクセスする前に置きます。その式の型からnull | undefinedを取り除きます。

type Box = { value?: number };
const box: Box = { value: 7 };
const n: number = box.value!; // value is number | undefined -> number
console.log(n);

ガード後に非 null をアサーションする

値が存在することを論理的に保証できていても、コンパイラーがその推論を追えない場合があります。!を使えば処理を続行できます。ただし、実際の実行時チェックのほうが通常は明確です。

const list: Array<string | null> = ['a', null, 'c'];
const present = list.filter((x) => x !== null);
// TS may still see string | null; assert if certain:
console.log(present[0]!.toUpperCase());

もう一度、コンパイル時のみ

asと同様に、!演算子は実行時に消去されます。チェックは一切行いません。値が実際には null の場合、コンパイラーが問題ないと判断していても、実行時エラーが発生します。

function risky(s: string | null): number {
  return s!.length; // no runtime guard
}
console.log(risky('hi'));
// risky(null) would throw at runtime

! の危険性

実際には null になり得る値に対して非 null をアサーションすると、隠れたバグを作ることになります。コンパイラーが警告しなくなるため、その null が本番環境で実際に現れるまでエラーが表面化しません。

type User = { name?: string };
const u: User = {};
// const len = u.name!.length; // compiles, crashes at runtime
console.log('name is undefined here -> ! would crash');

実際のチェックを優先する

可能な場合は、!を実際の null チェックまたはオプショナルチェーンに置き換えてください。安全な方法なら1行で済み、実行時クラッシュの原因となる問題を根本から排除できます。

type User = { name?: string };
function nameLen(u: User): number {
  if (u.name) return u.name.length; // checked
  return 0;
}
console.log(nameLen({ name: 'Ada' }), nameLen({}));

確定代入アサーション

関連する機能に確定代入アサーションがあります。let x!: Tと記述すると、宣言時に初期化されていなくても、使用前にxへ代入されるとコンパイラーに約束できます。

let token!: string; // promise: assigned before use
function init() { token = 'abc123'; }
init();
console.log(token.length);

クラスにおける確定代入

これは、コンストラクターではなく、フレームワークや初期化メソッドによってプロパティが設定されるクラスでよく使われます。プロパティ名の後ろに!を付けると、「確実に代入されていない」というエラーを抑制できます。

class Service {
  config!: { url: string }; // set later by setup()
  setup() { this.config = { url: '/api' }; }
}
const s = new Service();
s.setup();
console.log(s.config.url);

確定代入は慎重に使用する

確定代入アサーションも、コンパイラーが検証できない約束です。代入前にプロパティへアクセスすると、警告なしに実行時のundefinedを読み取ることになります。

class Late {
  data!: number[];
  read() { return this.data.length; } // crashes if called before init
}
const l = new Late();
l.data = [1, 2];
console.log(l.read());

! とオプショナルチェーン

?.で済む場合に!を使ってはいけません。オプショナルチェーンは実行時に null を安全に処理しますが、!はコンパイラーを黙らせるだけです。両者は異なる問題を解決します。

type Cfg = { db?: { host?: string } };
const c: Cfg = {};
console.log(c.db?.host ?? 'localhost'); // safe
// c.db!.host! would crash here

! が正当化される場合

コンパイラーでは表現できない確かな保証がある場合、!演算子を使うのは妥当です。たとえば、直前に追加してすぐに読み取る値などです。その場合でも、安全である理由を記録してください。

const cache = new Map<string, number>();
cache.set('hits', 0);
// We just set it, so get is non-null:
const hits = cache.get('hits')!;
console.log(hits);

理解度チェック

非 null アサーション演算子についての理解度を確認しましょう。

振り返り: 非 null アサーション

次のことを学びました。

  • 後置の ! は、コンパイル時にのみ型から null | undefined を取り除きます。
  • 実行時のチェックは一切行わないため、誤ったアサーションをすると、やはりクラッシュします。
  • let x!: T は、後から初期化する値に対する確定代入アサーションです。
  • 実際のチェックやオプショナルチェーンを優先し、! は本当に保証できる場合に限って使用してください。

次は、二重アサーションとそのリスクについて学びます。

const map = new Map<string, number>();
map.set('a', 1);
const v = map.get('a')!;
console.log(v);

よくある質問

「Non-nullアサーション演算子」レッスンは無料ですか?

はい。「Non-nullアサーション演算子」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「Non-nullアサーション演算子」で何を学びますか?

!演算子を使い、値がnullでもundefinedでもないことをアサートします。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Non-nullアサーション演算子」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型アサーションに使うasキーワード
  2. Non-nullアサーション演算子
  3. 二重アサーションとそのリスク
  4. アサーションと型ガード
← TypeScript Academyに戻る