型って、「書くのが面倒な決まりごと」に見えることがありますよね。

でも型は、バグを実行前に捕まえる仕組みであり、その歴史には設計者本人の謝罪まで残っています。今回は、「10億ドルの過ち」から、TypeScriptの型が実行時に消える話まで、型とnullをめぐる「ほぉー」を8つ集めました。1つでも知らなかったら儲けものです。

① nullは、発明者が「10億ドルの過ち」と謝っています

まず、有名すぎる話から。

nullを1965年に考案したトニー・ホーアは、2009年の講演でこう振り返りました。「あれは私の10億ドルの過ちだった」。

当時「実装が簡単だから」という理由で入れたnull参照が、その後世界中で無数のクラッシュとバグと脆弱性を生んだ——本人がそう認めているんです。

NullPointerException、ぬるぽ、セグフォ。私たちが日々戦っているあれは、半世紀前の一つの設計判断の子孫なんですよね。だから現代の言語は、この過ちを設計で正そうとしています。

② TypeScriptの型は、実行時には消えています

これは知らないと確実に事故ります。

TypeScriptの型注釈は、コンパイル(JavaScriptへの変換)の時点で、跡形もなく消えます。実行されるのは型情報のないただのJavaScriptです。だから、こう書いても守られません。

function f(x: number) { ... }
f(response.data);  // dataが実は文字列でも、実行時は素通り

外部から来るデータ(APIレスポンス、フォーム入力)は、型注釈があっても実行時には検証されない。「型を書いたのに実行時エラー」の正体はこれです。

境界では、実行時に実際に検証するコードが別途必要なんです。

③ 型の一致は、「名前」で決まるとは限りません

「同じ型かどうか」の判定方法に、実は2つの流派があります。

流派判定のしかた代表的な言語
公称型名前で判定。「Dog型」と「Cat型」は、中身が同じでも別物Java、C#
構造的型形で判定。同じメンバーを持っていれば、同じ型とみなすTypeScript、Goのインターフェース

TypeScriptでは、名前の違うオブジェクトでも、必要なプロパティが揃っていれば代入できてしまう。「アヒルのように歩き、アヒルのように鳴くなら、それはアヒル」というダックタイピングの考え方です。

同じ「型」という言葉でも、言語によって判定基準が正反対。移る時に一番戸惑うポイントなんです。

④ nullとundefined、2種類ある言語があります

JavaScriptには、「値が無い」を表すものが2つあります。

null(意図的に「無い」を入れた)と、undefined(そもそも設定されていない)。似ていますが、由来が違います。そして罠が、比較の挙動です。

null == undefined   // → true(緩い比較)
null === undefined  // → false(厳密な比較)

「無い」が2種類あり、比較方法で結果が変わる。だからJavaScriptでは === を使うのが定石——この助言の背景には、こういう歴史的事情があるんです。

⑤ 現代の言語は、「nullかもしれない」を型で強制します

①のホーアの過ちへの、言語からの回答です。

KotlinやSwift、TypeScriptの厳格モード(strictNullChecks)などでは、「nullが入りうる」ことを型で明示しないと、nullを扱えません。

let a: string = null;         // エラー:nullは入れられない
let b: string | null = null;  // OK:「nullもある」と宣言して初めて許される

そして string | null 型は、nullチェックを通すまで、文字列として使わせてもらえません。コンパイラが強制するんです。

つまりNullPointerExceptionを、実行時ではなくコンパイル時に潰せる。「10億ドルの過ち」を、型で封じ込める仕組みなんです。

⑥ any は、型システムに空けた穴です

TypeScriptで型エラーに困ったとき、anyを付けると黙ります。でもこれ、その変数から先の型チェックを全部無効化する危険な操作です。

anyは「何でもあり」の型。一度anyにすると、そこを通ったデータは型の保護を失って伝播します。エラーが消えたのではなく、チェックを止めただけなんですよね。

「本当に型が分からない」ときの正解は、anyではなくunknown。unknownは「使う前に必ず種類を確認せよ」と強制するので、安全なんです。

anyは型システムに空けた穴。塞ぐ相手であって、頼る相手ではないんです。

⑦ 「型を書く」と「型を推論させる」は、両立します

「型付き言語は、いちいち型を書くから面倒」——これも半分は誤解です。現代の型システムは型推論が強力で、多くの場面で書かなくても型を言い当ててくれます。

const nums = [1, 2, 3];                       // number[] と自動で分かる
const total = nums.reduce((a, b) => a + b);   // numberと分かる

だから実務の勘所は、「境界には明示的に書き、内部は推論に任せる」。関数の引数と戻り値、外部との境界だけしっかり型を付ければ、中身は推論が面倒を見てくれる。

型は「全部書く」でも「全部省く」でもなく、効かせどころを選ぶものなんです。

⑧ 型を、状態そのものにできます

最後は、型の一番かっこいい使い方です。

「読み込み中」「成功(データあり)」「失敗(エラーあり)」——この3状態を、boolフラグの組み合わせで持つと、「成功なのにエラーもある」というあり得ない状態が表現できてしまいます。

型で状態を設計すると、これをそもそも作れなくできます(判別可能なユニオン型)。

type State =
  | { status: "loading" }
  | { status: "success"; data: User }
  | { status: "error";   error: Error };

成功のときだけdataがあり、失敗のときだけerrorがある、と型で縛る。

「あり得ない状態を、そもそも書けなくする」。これが型の到達点で、テストで防ぐより一段強い。バグを、実行時ではなく設計時に消す発想なんです。

番外編:知っておくと会話が深くなる話

「型が通れば、だいたい動く」
関数型言語の世界には、「型検査が通ったら、もう動いたも同然」という感覚があります。強い型システムは、テストの一部を肩代わりしてくれるんですよね。

ジェネリクスは「型の関数」です
List<T> の T は、型を受け取って型を返す仕組み。値を扱う関数があるように、型を扱う関数がある、と考えると腑に落ちます。

「?」の意味
多くの言語で、型やプロパティに付く ? は「無いかもしれない」の印です。user?.name は「userがあれば.nameを、無ければundefinedを」。①の過ちと向き合うための、日常的な道具なんです。

RJCでも、型と向き合っています

RJCが携わる保険や金融のシステムは、状態の取り違えが事故に直結する世界です。⑧の「あり得ない状態を作れなくする」設計は、品質をコードの構造で担保する考え方なんですよね。

研修でもReactやTypeScriptを扱いますし、こういう仕組みの話をTechチームで共有しながら開発しています。

よくいただくご質問

Q. まずどれから押さえるべきですか?
A. ②かなと思います。「型は実行時に消える」を知らないと、外部データの検証を丸ごと忘れる事故になるんですよね。

Q. anyは、絶対に使ってはいけませんか?
A. 最終手段としてはありますが、まずunknownを検討です(⑥)。「型が分からない」と「型チェックを止める」は別物なので、意図して使うのが大事です。

Q. 型を書くのが大変で、挫折しそうです…
A. ⑦のとおり、全部書く必要はありません。境界だけ書いて中は推論に任せる、から始めると、負担のわりに効果が大きいです。

Q. 未経験からでも、分かるようになりますか?
A. なります。型は「箱に貼るラベル」の比喩から入れて、⑧の「あり得ない状態を禁止する」まで、段階で理解できる分野なんです。

型は、未来のバグへの手紙です

今日の8つに共通していたのは、これでした。

型を書くことは、「このデータはこういうものだ」という約束を、コンパイラと未来の自分に残すことです。①の過ちを型で封じ、⑧であり得ない状態を消す。

型は制約ではなく、バグが生まれる前に捕まえる網。面倒がる対象ではなく、味方につける相手なんですよね。

みなさんが型に助けられた(あるいは泣かされた)話、よかったら教えてください。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?