TypeScript で null, undefined を安全に取り扱う方法

TypeScript ではコンパイラオプションの stricttrue にすることで null, undefined を安全に取り扱える Null 安全な状況を保証することができます。

コンパイルオプションの設定

tsconfig.json ファイルを編集し以下の例の様に strict オプションを true に設定します。

{
  "compilerOptions": {
    "strict": true,
  },
}

このオプションのデフォルト値は false なため、明示的に設定しないと有効にはなりません。

コンパイルオプションによる変化

コンパイラオプションで strict を有効にすると Union 型を利用して undefined を明示していない型の変数に undefined を代入することが出来なくなります。 (正確には strict を有効にすると有効になる strictNullChecks が有効になった影響です。) これにより undefined が明示されていない変数に undefined が代入されることが無くなります。

// これはコンパイルエラーになります
let name: string = undefined;

// undefined を代入するには Union 型を利用して undefined である可能性があることを明示する必要があります
let name: string | undefined = undefined;

undefined である可能性がある変数を undefined が許容されていない変数に代入するためには null チェックが必要になります。

declare const input: string | undefined;

if (input) {
  // ここでは input の null チェックが完了しているため input: string として利用できます
  const input1: string = input;
}

// ここでは input の null チェックが完了していないため、この代入はコンパイルエラーが発生します
const input2: string = input;

TypeScript の型チェックは優秀なため以下の様な手順での null チェックが可能です。

function test(input: string | undefined): void {
  if (!input) {
    // JavaScript の仕様の都合上 input は undefined と "" の可能性があるため undefined だとは限りません
    const i: string | undefined = input
  }

  if (input) {
    // if 文の中では input の null チェックが行われているので input は undefined ではありません
    const i1: string = input;
  }

  // ここは input が undefined の場合でも到達可能なため、この代入ではコンパイルエラーが発生します
  const i2: string = input;

  if (!input) {
    return;
  }

  // 直前の null チェックの結果 undefined であった場合は return されていて到達できないため input は undefined でないことが保証されています
  const i3: string = input;
}

JavaScript からの利用

null 安全は TypeScript の機能のため JavaScript から実行される関数や JavaScript 上で取り扱われる変数に関しては型定義による安全性の確保が必要です。 JavaScript 側からの入力に関しては undefined の可能性を考慮したり unknown を利用する必要があります。

export function methodUseFromJavaScript1(input: string | undefined): void {
}

export function methodUseFromJavaScript2(input?: string): void {
}

export function methodUseFromJavaScript3(input: unknown): void {
}

参考資料