6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年3月29日 りあクト! 第4章 TypeScriptで型をご安全に(p.183~)

型のNull安全性を保証する

TypeSctriptはデフォルトの設定では全ての型にnullとundefinedを代入出来てしまいます。 これではnull安全性が保証されず、静的型付け言語を使っているのに実行エラーが頻発しかねません。

厳密にnullやundefindと他の型を厳密に区別するにはstrictNullCheckをコンパイルオプションで設定します。

なぜデフォルトで設定されていないのか

TypeScriptは過去、null安全性が保証されていない言語でした。
そのためバージョンを上げた際も過去に書かれたコードとの後方互換性を保てるように任意で設定する仕様となっています。

tsconfig.jsonでnullとundefinedを他の型と区別する設定にする

tsconfig.jsonファイル

{
    //省略
    "strictNullChecks": true
}
  • この設定を加えることでnullundefinedを他の型と区別することができます。
  • 設定していないとどの型にもnullundefinedは代入できてしまいます。

strict trueの設定にも含まれています。

nullを許容する場合の書き方

let foo: string | null = 'fuu';
foo = null;
  • 変数fooに対してstringnull の共用体型を指定しています。

null安全性が保証されることで 以下のコードでは、getMomNameの定義でコンパイルエラーが発生します。

type Resident = {
  familyName: string;
  lastName: string;
  mom?: Resident;
};

// Object is possibly 'undefined'.(2532)
const getMomName = (resident: Resident): string => resident.mom.lastName;
 
const patty = { familyName: 'Hope-Rabbit', lastName: 'patty'};
  • Resident型のmomが省略可のため、getMomNameに渡されるオブジェクトのmomが省略されている可能性があるためコンパイルエラーが発生します。
  • 「この場合だとnullやundefinedが入るかもしれませんよ?」というエラーです。
    (下で説明される非Nullアサーション演算子はそれに対して「絶対に入らんからええねん!」という記法です。)

推奨はされていませんが nullundefinedも入らないことをコンパイラに伝えるためには、非Nullアサーション演算子を使います。ただし、コンパイラを黙らせているだけで、実行時にエラーになる可能性があり静的型付け言語の恩恵が受けられなくなってしまうため、書籍でのチームでは使わない方針という説明がされていました。

// !が非Nullアサーション
// resident.momでundefinedとnullを返さないことを強制する
const getMomName = (resident: Resident): string => resident!.mom.lastName;

参考

りあクト! 【Ⅰ. 言語・環境編】 p.183~