TypeScript:基本の型注釈
1学習の目的
- number・string・boolean に加え、null・undefined・any といった基本の型を使い分けられるようになる。
- any の危険性を理解する。型を付けたつもりで実は何も守られていない、という状態を避けられるようになる。
2基礎解説
| 型 | 入る値 | 例 |
|---|---|---|
| number | 数値(整数も小数も) | 42, 3.14, -5 |
| string | 文字列 | "ノートPC" |
| boolean | 真偽値 | true, false |
| any | 何でも(危険) | 型チェックが効かない |
- JavaScriptと違い、整数と小数の区別は無い。どちらも number で表す。42 も 3.14 も同じ型。
- any は「何でも入る型」で、TypeScriptの利点をすべて捨てる。付けた瞬間から型チェックが効かなくなるため、使わずに済む書き方をまず考える。
- 厳格モードでは null を number 型の変数に入れられない。「値が無いかもしれない」場合は、別の書き方が必要になる(TS08で扱う)。
- 型が合わない代入は、実行する前にエラーになる。const n: number = "42"; はエディタ上で赤線が引かれる。
- ただし文字列と数値の + は許される。"1" + 2 は文字列 "12" になり、これは型として正しい。JS03で学んだ罠は、TypeScriptでも完全には防げない。
現場使用例:APIから受け取った値の型を明示する、設定値の型を固定する、計算結果の型を保証する。型を書く場所を選ぶ判断が、実務では重要になる。
// 基本の3つ
const price: number = 128000;
const productName: string = "ノートPC";
const inStock: boolean = true;
// ❌ 型が違うとエラー(実行前に分かる)
const wrong: number = "42";
// → Type 'string' is not assignable to type 'number'.
// ⚠ any は何でも入ってしまう(型チェックが効かない)
let anything: any = 1;
anything = "文字列"; // エラーにならない
anything = true; // これも通る
// 数値に整数・小数の区別は無い
const count: number = 42;
const rate: number = 0.08;
// 数値の書式変換はJavaScriptと同じ
console.log((3.14159).toFixed(2)); // 3.14
console.log((128000).toLocaleString()); // 128,000
console.log(Number("42") + 1); // 43
3基本ドリル(10問)
出力 == 42 3.14
整数も小数も同じ number 型。console.log(a, b) で並べて出力できる。
const count: number = 42; const rate: number = 3.14; console.log(count, rate);
TypeScriptには整数型と小数型の区別が無い。どちらも number でまとめて扱う。他の言語(Javaなど)とはここが違う。
A. エラーになる B. エラーにならない C. 警告が出る D. 実行時に落ちる 選択★☆☆無料
解答 == B
any は「何でも入る型」。
B
any は型チェックを無効にする。書けてしまうが、TypeScriptを使う意味が失われる。「とりあえず any」は最も避けたい書き方。
出力 == 3.14
toFixed(2) を使う。JavaScriptと同じメソッドが使える。
const pi: number = 3.14159; console.log(pi.toFixed(2));
number 型に使えるメソッドはJavaScriptと同じ。型を付けたことで、エディタが使えるメソッドを候補表示してくれるようになる。
const message: ____ = "こんにちは"; console.log(message);
出力 == こんにちは
文字列を表す型。小文字で6文字。
string
すべての型名は小文字。String(大文字)とは別のものを指すので、必ず小文字で書く。
A. 型が分からないときは常に使う B. できるだけ使わない C. すべての変数に使う D. 数値に使う 選択★☆☆無料
解答 == B
any を使うと何が失われるか。
B
any は「最後の手段」。外部ライブラリの型が不明な場合など限られた場面のみ。多用すると、型のあるJavaScriptではなく、ただのJavaScriptに戻ってしまう。
出力 == 140800
Number() で変換する。変換前は string、変換後は number になる。
const input: string = "128000"; const price: number = Number(input); const taxed: number = Math.round(price * 1.1); console.log(taxed);
型が変わる場面では、変数を分けるのが安全。同じ変数を使い回すと「今どっちの型なのか」が分からなくなる。
const isPublished: ____ = false; console.log(isPublished ? "公開中" : "非公開");
出力 == 非公開
true / false を表す型。小文字で7文字。
boolean
boolean は2つの値しか取らないので、型として最も厳密なもののひとつ。フラグや状態の管理に使う。
A. 0が入る B. エラーになる C. null が入る D. undefined になる 選択★★☆無料
解答 == B
number 型に null は含まれるか。
B
厳格モードでは null と number は別の型。「値が無いかもしれない」ことを表すには専用の書き方が必要になる(TS08)。この厳しさが、JS17で悩まされたNULL関連のバグを防いでくれる。
出力 == キーボード/在庫18個/販売中
3種類の型を使う。販売状態は三項演算子で切り替える。
const productName: string = "キーボード";
const stock: number = 18;
const onSale: boolean = true;
console.log(`${productName}/在庫${stock}個/${onSale ? "販売中" : "販売停止"}`);
3つの基本型を1つの処理で使い分ける。実務のデータは必ず複数の型が混在するので、この組み合わせが基本形になる。
出力 == 12
文字列と数値を + でつなぐと、結果は文字列になる(JS03)。型注釈は string。
const a: string = "1"; const b: number = 2; const result: string = a + b; console.log(result);
TypeScriptでもこの罠は防げない。"1" + 2 は文字列として正しいので、型エラーにならない。JS03で学んだ注意点は、TypeScriptでもそのまま有効。
4実践シナリオ(5問)
出力 == 小計:25,500円
入力は string、変換後は number。Number() で変換する。
const qtyInput: string = "3";
const priceInput: string = "8500";
const qty: number = Number(qtyInput);
const price: number = Number(priceInput);
const subtotal: number = price * qty;
console.log(`小計:${subtotal.toLocaleString()}円`);
フォームの入力は必ず文字列で届く(JS12で学んだ input.value と同じ)。TypeScriptなら「ここはまだ文字列」「ここから数値」が型として明示されるので、変換忘れに気づきやすい。
出力 == 割引率:15.0%
割引率 =(定価−割引後)÷ 定価 × 100。toFixed(1) で桁を揃える。
const listPrice: number = 20000;
const salePrice: number = 17000;
const rate: number = ((listPrice - salePrice) / listPrice) * 100;
console.log(`割引率:${rate.toFixed(1)}%`);
計算の途中も number 型のまま。toFixed の結果だけは文字列になる点に注意(表示用に変換されるため)。
出力 == 2001
any には何でも代入できる。"200" + 1 は文字列連結になる。
let value: any = 100; value = "200"; console.log(value + 1);
期待した 201 ではなく 2001 になる。any を使ったため、TypeScriptは何も警告してくれなかった。これがanyの危険性——型を書いているのに、まったく守られていない状態になる。
「税込:140,800円」
「税抜:128,000円」
「消費税:12,800円」 コーディング★★★無料
出力3行が完全一致
税抜 = 税込 ÷ 1.1(四捨五入)。税額 = 税込 − 税抜。
const taxIncluded: number = 140800;
const taxExcluded: number = Math.round(taxIncluded / 1.1);
const tax: number = taxIncluded - taxExcluded;
console.log(`税込:${taxIncluded.toLocaleString()}円`);
console.log(`税抜:${taxExcluded.toLocaleString()}円`);
console.log(`消費税:${tax.toLocaleString()}円`);
逆算では引き算で差額を求めるのが安全。税額も別途 Math.round(taxExcluded * 0.1) で計算すると、丸め誤差で1円合わないことがある。
「モニター」
「単価区分:高額」(3万円以上なら「高額」、それ未満は「通常」)
「在庫評価額:315,000円」 コーディング★★★無料
出力3行が完全一致
区分の判定結果は string 型の変数に入れる。在庫評価額は単価×在庫。
const productName: string = "モニター";
const price: number = 45000;
const stock: number = 7;
const priceClass: string = price >= 30000 ? "高額" : "通常";
const stockValue: number = price * stock;
console.log(productName);
console.log(`単価区分:${priceClass}`);
console.log(`在庫評価額:${stockValue.toLocaleString()}円`);
priceClass は string 型だが、実際には「高額」か「通常」しか入らない。今の書き方ではどんな文字列でも代入できてしまう。TS06のリテラル型を学ぶと、この2つだけに限定できるようになる。
5仕上げ課題
フォームからの入力(すべて文字列で届く)
・商品名 nameInput:「ノートPC」
・単価 priceInput:「128000」
・数量 qtyInput:「2」
・会員フラグ memberInput:「true」
処理
① 単価と数量を数値に変換する
② 会員フラグを真偽値に変換する("true" という文字列と比較して判定)
③ 小計 = 単価 × 数量
④ 会員割引 = 会員なら小計の10%(四捨五入)、非会員なら0
⑤ 合計 = 小計 - 割引
すべての変数に型注釈を付けること。変換前(文字列)と変換後(数値・真偽値)は別の変数にする。
期待される出力(5行)
商品:ノートPC
単価:128,000円 × 2
小計:256,000円
割引:-25,600円
合計:230,400円
出力5行が完全一致
文字列→数値は Number()、文字列→真偽値は memberInput === "true" で判定する。変換前の変数は string 型、変換後は number / boolean 型で宣言する。
const nameInput: string = "ノートPC";
const priceInput: string = "128000";
const qtyInput: string = "2";
const memberInput: string = "true";
const price: number = Number(priceInput);
const qty: number = Number(qtyInput);
const isMember: boolean = memberInput === "true";
const subtotal: number = price * qty;
const discount: number = isMember ? Math.round(subtotal * 0.1) : 0;
const total: number = subtotal - discount;
console.log(`商品:${nameInput}`);
console.log(`単価:${price.toLocaleString()}円 × ${qty}`);
console.log(`小計:${subtotal.toLocaleString()}円`);
console.log(`割引:-${discount.toLocaleString()}円`);
console.log(`合計:${total.toLocaleString()}円`);
この課題の核心は「型が変わる境界を明示する」ことだ。フォームから届くのはすべて文字列で、そのまま計算に使うと "128000" * "2" のような危うい処理になる。変換前と変換後で変数を分け、それぞれに型注釈を付けることで、どこまでが文字列で、どこから数値なのかがコードに刻まれる。
とくに const isMember: boolean = memberInput === "true"; の行に注目してほしい。文字列 "true" と真偽値 true はまったく別物で、if (memberInput) と書くと文字列 "false" でも真と判定されてしまう(JS03で学んだ罠)。明示的に比較して boolean に変換する必要がある。
もしここで any を使っていたら、これらの問題はすべて素通りしていた。型を書く価値は、こうした境界でこそ発揮される。
次章では配列とオブジェクトの型を学ぶ。1つの値ではなく、データのまとまりに型を付けられるようになる。