はじめに
TypeScript(以下 TS)は JavaScript に型システムを追加した言語です。
「string / number / boolean などがある」
ということは知っていますが、より実務で型を使いこなせるよう理解を深めてみようと思いました。
この記事では、
- 各型がなぜ存在するのか
- どんな場面で使うと安全になるのか
- 使わないと何が困るのか
について解説します。
対象者
- JavaScriptは書いたことがあり、TypeScriptの型定義に疑問がある人
※ 本記事では TypeScript の型のうち、プリミティブ型に絞って解説します。
オブジェクト系の型({ foo: string } / interface など)や、設計に関わる型(any / never など)については、別記事で扱います。
プリミティブ型について
プリミティブ型とは?
→ それ以上分解できない最小単位の値のことです。
TypeScriptはまずここを厳密にしています。
TypeScriptが厳密に扱うプリミティブ型
- string:文字列
- number:数値
- boolean:真偽値
- bigint:非常に大きな整数
- symbol:一意な識別子
- null / undefined:値が存在しない状態
上記の中からよく目にする型について、今一度ご紹介していきたいと思います。
string
文字列を表します。
let name: string ="こんにちは";
なぜ必要?
JavaScriptでは数値と文字列が混ざりやすく、
意図しない文字列結合が起きます。
10 + "1"; // "101"
TypeScriptではこれを事前に防ぐことができます。
number
number は TypeScript において「数値であること」を保証する型です。
let price: number = 1200;
なぜ必要?
この型を付けることで、数値として扱えない値が混入するのをコンパイル時に防止できます。
より実務的な例だと、以下のような使い方も可能です。
number リテラル型との組み合わせ
TypeScript では 特定の数値そのものを型として扱うこともできます。
type HttpStatus = 200 | 400 | 404 | 500;
let status: HttpStatus = 200;
status = 404; // ⭕
status = 403; // ❌ エラー
👉 「取り得る数値を制限する」 という
TypeScript ならではの強力な使い方です。
Union 型による柔軟な数値設計
let value: number | null;
value = 10; // ⭕
value = null; // ⭕
value = "10"; // ❌
- まだ数値が確定していない状態
- 未入力・未計算の状態
を 型として正しく表現できます。
number 型を使うと設計が明確になる
function calculateTotal(price: number, taxRate: number): number {
return price * (1 + taxRate);
}
この関数から読み取れること:
- 引数は 必ず数値
- 戻り値も 必ず数値
- 呼び出し側は迷わない
👉 型が仕様書の役割を果たすのが TypeScript の強みですね。
boolean
boolean は TypeScript において「真か偽かの状態を厳密に表すための型」です。
単に true / false を扱うだけでなく、条件分岐の前提を保証する役割を持ちます。
let isPublished: boolean = false;
boolean を型として明示する意味
TypeScriptでは、boolean を指定することで次のことが保証されます。
-
true / false以外の値が代入されない - 条件分岐の意図が明確になる
- 状態を表す変数であることが一目で分かる
let isCompleted: boolean = true;
isCompleted = false; // ⭕
isCompleted = "true"; // ❌ エラー
isCompleted = 1; // ❌ エラー
条件分岐との関係
function submit(isValid: boolean) {
if (isValid) {
// 正常処理
}
}
- 呼び出し側は 真偽値を渡し、正常処理・異常処理などの条件分岐を行う
-
"ok"や1のような曖昧な値は渡せない
boolean を増やしすぎない設計も重要
let isLoading: boolean;
let isError: boolean;
let isSuccess: boolean;
とはいえ真偽の判定は何でもboolean型にするべきではありません。
このような状態で組み合わせが多すぎるとかえって読みにくいコードになります。
その場合は boolean + Literal型 による設計が有効です。
type Status = "loading" | "success" | "error";
let status: Status = "loading";
👉 2択の場合にboolean は強力ですが、選択肢が多い場合はステータスも持たせてあげると可読性が高まります。
null
null は「値が意図的に存在しない」ことを表す型です。
TypeScriptでは、これを 明示的な状態として扱います。
let selectedUser: User | null = null;
null を使う理由
- まだ選択されていない
- 明示的にリセットした
- 「存在しない」ことに意味がある
null チェックを強制できる
function getUserName(user: User | null): string {
if (user === null) {
return "未選択";
}
return user.name;
}
TypeScriptは、
null の可能性を考慮しないコードを許可しません。
👉 これが 実行時のエラー予防となります。
undefined
undefined は「まだ値が設定されていない状態」を表す型です。
let result: number | undefined;
undefined が発生する例
- 初期化されていない変数の場合
- オプショナルプロパティの場合
- 戻り値が存在しない可能性がある場合
interface User {
name: string;
email?: string; // email: string | undefined
}
undefined を扱うときの考え方
function getEmail(user: User): string | undefined {
return user.email;
}
呼び出し側は、
- 値がある前提で書けない
- しかし、チェックが必須
const email = getEmail(user);
if (email !== undefined) {
console.log(email);
}
👉 「まだ決まっていない状態」を安全に表現できるのが undefinedです。
null と undefined の使い分け
| 状態 | 使う型 |
|---|---|
| 意図的に存在しない | null |
| 未設定・不明 | undefined |
👉 混在させない設計が読みやすさに直結します。
boolean / null / undefined
- boolean:状態が2択であることを保証
- null:存在しないことを仕様として表す
- undefined:未確定・未設定を安全に表す
これらを正しく使うことで、
- 条件分岐が明確になる
- 実行時エラーが起きにくくなる
- コードの可読性が上がる
まとめ
- TypeScriptの型は、値を縛るためではなく設計の意図をコードに残すために存在します。
-
boolean/null/undefinedは、状態や不確定さを安全に表現するために、きちんと使い分けましょう。 - 型を正しく使うことで、実行前に不整合を検知でき、コードの信頼性が高まります。
- TypeScriptは「書けば書くほど、コードが自分を助けてくれる言語」であるとも言えますね。
記事を読んでくださった方は、是非弊社開発課のXもフォローしてください。
毎日エンジニアに向けた情報発信を行っています。