TypeScript
JavaScriptに「型」を追加した言語
TypeScriptとは?
日常での例え:ラベル付きの収納ボックス
箱に何でも入れられる
→ 開けてみるまで中身が分からない
「おもちゃ用」「服用」とラベルがある
→ 間違ったものを入れようとすると警告
なぜTypeScriptが必要?
JavaScriptだけだと起きる問題:
- 数字を期待している関数に文字列を渡してしまう
- 存在しないプロパティにアクセスしてエラー
- タイプミスに実行するまで気づけない
TypeScriptなら:コードを書いている時点でエラーを教えてくれる!
TypeScriptとJavaScriptの関係
TypeScript = JavaScript + 型
TypeScriptは最終的にJavaScriptに変換(コンパイル)されて実行されます。
つまり、JavaScriptの知識はそのまま使えます!
TypeScriptでできること
型安全
特徴コンパイル時にエラーを検出
型推論
便利自動で型を推測してくれる
IDE補完
便利コード補完が強力になる
ドキュメント
特徴型がコードの説明書になる
バグ防止
重要実行前にミスを発見
リファクタリング
重要安全にコード変更できる
コード例
基本的な型指定
変数に型を付ける
// 型を指定
let name: string = "田中";
let age: number = 25;
let isStudent: boolean = true;
// 型が違うとエラー!
name = 123; // ❌ エラー: string型にnumberは代入できない
age = "二十五"; // ❌ エラー: number型にstringは代入できない
// 型推論(自動で型を推測)
let city = "東京"; // 自動的にstring型
let score = 100; // 自動的にnumber型JavaScriptだと?
JavaScript(型チェックなし)
let name = "田中";
let age = 25;
// 何でも代入できてしまう
name = 123; // ⚠️ エラーにならない
age = "二十五"; // ⚠️ エラーにならない
// 実行時に予期せぬ動作...
console.log(name.toUpperCase());
// → TypeError: name.toUpperCase is not a function
// (数値には toUpperCase がない!)TypeScript(型チェックあり)
let name: string = "田中";
let age: number = 25;
// 型が違うとコンパイル時にエラー
name = 123; // ❌ コンパイルエラー!
age = "二十五"; // ❌ コンパイルエラー!
// 実行前に問題を発見できる
// → バグを未然に防げる!JSは「動的型付け」なので実行時まで型エラーに気づけない。TSは「静的型付け」なのでコードを書いている時点でエラーを教えてくれる。
配列とオブジェクトの型
複合的なデータ構造の型
// 配列の型
let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["田中", "鈴木", "佐藤"];
// オブジェクトの型
let user: {
name: string;
age: number;
email: string;
} = {
name: "田中太郎",
age: 25,
email: "tanaka@example.com"
};
// 存在しないプロパティはエラー
user.address; // ❌ エラー: 'address'は存在しないJavaScriptだと?
JavaScript
let user = {
name: "田中太郎",
age: 25,
email: "tanaka@example.com"
};
// タイプミスしても気づけない
console.log(user.adress); // ⚠️ undefined
// "address"のつもりが"adress"...
// 配列に何でも入る
let numbers = [1, 2, "三", true];
// ⚠️ 数値配列のはずが混在TypeScript
let user: {
name: string;
age: number;
email: string;
} = { ... };
// タイプミスをすぐに検出
console.log(user.adress); // ❌ エラー!
// → "adress"は存在しません
// 配列の型も守られる
let numbers: number[] = [1, 2, "三"];
// ❌ エラー: stringは入れられないJSでは存在しないプロパティにアクセスするとundefinedが返る。TSではコンパイル時にエラーになるのでタイプミスを防げる。
関数の型
引数と戻り値に型を付ける
// 引数と戻り値の型
function greet(name: string): string {
return "こんにちは、" + name + "さん!";
}
greet("田中"); // ✅ OK
greet(123); // ❌ エラー: numberはstringに代入できない
// アロー関数
const add = (a: number, b: number): number => {
return a + b;
};
// 戻り値がない関数
function log(message: string): void {
console.log(message);
}JavaScriptだと?
JavaScript
function greet(name) {
return "こんにちは、" + name + "さん!";
}
greet("田中"); // "こんにちは、田中さん!"
greet(123); // "こんにちは、123さん!" ⚠️
greet(); // "こんにちは、undefinedさん!" ⚠️
// 引数を忘れても、型を間違えても
// エラーにならず実行されてしまうTypeScript
function greet(name: string): string {
return "こんにちは、" + name + "さん!";
}
greet("田中"); // ✅ OK
greet(123); // ❌ エラー: 型が違う
greet(); // ❌ エラー: 引数が足りない
// 間違った使い方を事前に防げる
// IDEの補完も効く!JSでは引数の型も個数もチェックされない。TSでは関数の「正しい使い方」が型で定義され、間違えるとすぐに教えてくれる。
Union型(複数の型を許容)
「AまたはB」という型
// string または number を許容
let id: string | number;
id = "abc123"; // ✅ OK
id = 12345; // ✅ OK
id = true; // ❌ エラー: booleanは許可されていない
// null を許容する
let username: string | null = null;
username = "田中"; // ✅ OK
username = null; // ✅ OK
// 関数の引数でも使える
function printId(id: string | number) {
console.log("ID:", id);
}JavaScriptだと?
JavaScript
let id;
id = "abc123"; // OK
id = 12345; // OK
id = true; // OK(何でも入る)
id = {}; // OK(オブジェクトも)
id = []; // OK(配列も)
// 何が入っているか分からない
// → 使う側が常に確認が必要
if (typeof id === "string") {
// 文字列として処理
}TypeScript
let id: string | number;
id = "abc123"; // ✅ OK
id = 12345; // ✅ OK
id = true; // ❌ エラー!
id = {}; // ❌ エラー!
id = []; // ❌ エラー!
// 許可された型だけが入る
// → IDEも補完してくれる
// → 安心して使えるJSには「この変数には文字列か数値だけ」という制限がない。TSのUnion型は「許可する型を明示的に指定」できる。
型エイリアス(type)
型に名前を付けて再利用
// 型エイリアスの定義
type User = {
id: number;
name: string;
email: string;
};
// 再利用できる
const user1: User = {
id: 1,
name: "田中",
email: "tanaka@example.com"
};
const user2: User = {
id: 2,
name: "鈴木",
email: "suzuki@example.com"
};
// 配列でも使える
const users: User[] = [user1, user2];JavaScriptだと?
JavaScript
// 型の定義ができない
const user1 = {
id: 1,
name: "田中",
email: "tanaka@example.com"
};
// 別のユーザーを作るとき...
const user2 = {
id: 2,
nama: "鈴木", // ⚠️ タイプミス!
mail: "suzuki@example.com" // ⚠️ emailじゃない!
};
// エラーにならない...TypeScript
// 型を一度定義
type User = {
id: number;
name: string;
email: string;
};
// 型に従わないとエラー
const user2: User = {
id: 2,
nama: "鈴木", // ❌ エラー: namaは存在しない
mail: "..." // ❌ エラー: mailは存在しない
};
// すぐに気づける!JSではオブジェクトの「正しい形」を定義できない。TSの型エイリアスは「設計図」として機能し、統一された構造を強制できる。
オプショナルプロパティ
「あってもなくてもいい」プロパティ
type User = {
id: number;
name: string;
email?: string; // ? をつけると省略可能
};
// emailはなくてもOK
const user1: User = {
id: 1,
name: "田中"
};
// emailがあってもOK
const user2: User = {
id: 2,
name: "鈴木",
email: "suzuki@example.com"
};JavaScriptだと?
JavaScript
const user1 = {
id: 1,
name: "田中"
// emailがない
};
const user2 = {
id: 2,
name: "鈴木",
email: "suzuki@example.com"
};
// どちらが「正しい」か分からない
// emailは必須?任意?
// → コメントやドキュメントを見るしかないTypeScript
type User = {
id: number;
name: string;
email?: string; // ? = 任意
};
const user1: User = {
id: 1,
name: "田中" // ✅ emailなしでOK
};
// 型を見れば「emailは任意」と
// 一目で分かる!
// IDEのヒントでも表示されるJSでは「このプロパティは必須?任意?」がコードから読み取れない。TSの?は「省略可能」を明示し、コードが自己文書化される。
JavaScript vs TypeScript
JavaScript
function greet(name) {
return "Hello, " + name;
}
greet(123); // 実行時まで
// エラーに気づけないTypeScript
function greet(name: string) {
return "Hello, " + name;
}
greet(123); // ❌ コンパイル時に
// エラーを検出!