TypeScriptとは
TypeScriptは、JavaScriptに「型」の概念を追加したプログラミング言語です。Microsoftが開発し、現在はReact、Vue、Angular、Node.jsなど多くのプロジェクトで標準的に使用されています。
TypeScriptのコードは最終的にJavaScriptに変換(コンパイル)されるため、ブラウザやNode.jsでそのまま実行できます。既存のJavaScriptコードに段階的にTypeScriptを導入することも可能です。
なぜTypeScriptを使うのか
バグ削減
型エラーを実行前に検出
可読性向上
コードの意図が明確に
開発効率
強力な自動補完
チーム開発
コードの理解が容易
基本的な型の使い方
プリミティブ型
最も基本的な型です。変数名の後に : 型名 を付けて型を指定します。
// 文字列型
const name: string = "田中太郎";
const greeting: string = `こんにちは、${name}さん`;
// 数値型
const age: number = 25;
const price: number = 1980.5;
// 真偽値型
const isActive: boolean = true;
const hasPermission: boolean = false;
// 型が合わないとエラー!
// const age: number = "25"; // Error: 文字列を数値型に代入
配列型
配列の型は 型名[] または Array<型名> で指定します。
// 文字列の配列
const fruits: string[] = ["りんご", "バナナ", "オレンジ"];
// 数値の配列
const scores: number[] = [85, 92, 78, 95];
// Array形式でも書ける
const names: Array<string> = ["田中", "鈴木", "佐藤"];
// 配列操作も型安全
fruits.push("ぶどう"); // OK
// fruits.push(123); // Error: number は string に代入不可
// 配列メソッドの戻り値も型推論される
const doubled = scores.map(score => score * 2); // number[]型
オブジェクト型
オブジェクトのプロパティごとに型を指定できます。
// インラインでオブジェクトの型を定義
const user: { name: string; age: number; isAdmin: boolean } = {
name: "田中太郎",
age: 25,
isAdmin: false
};
// オプショナルプロパティ(?をつける)
const product: { name: string; price: number; description?: string } = {
name: "Tシャツ",
price: 2980
// descriptionは省略可能
};
インターフェースと型エイリアス
インターフェース(interface)
複雑なオブジェクトの型を再利用可能な形で定義します。
// ユーザー情報の型を定義
interface User {
id: number;
name: string;
email: string;
age?: number; // オプショナル
readonly createdAt: Date; // 読み取り専用
}
// インターフェースを使用
const user: User = {
id: 1,
name: "田中太郎",
email: "tanaka@example.com",
createdAt: new Date()
};
// user.createdAt = new Date(); // Error: readonlyは変更不可
// インターフェースの拡張
interface AdminUser extends User {
role: "admin" | "superadmin";
permissions: string[];
}
const admin: AdminUser = {
id: 100,
name: "管理者",
email: "admin@example.com",
createdAt: new Date(),
role: "admin",
permissions: ["read", "write", "delete"]
};
型エイリアス(type)
typeを使うと、より柔軟な型定義が可能です。
// 基本的な型エイリアス
type ID = string | number; // ユニオン型
type Status = "pending" | "active" | "completed"; // リテラル型
const userId: ID = "user_123"; // OK
const orderId: ID = 456; // OK
const status: Status = "active"; // OK
// const status: Status = "unknown"; // Error!
// オブジェクト型の定義
type Product = {
id: number;
name: string;
price: number;
category: "食品" | "衣料" | "家電";
};
// 交差型(複数の型を組み合わせ)
type Timestamped = {
createdAt: Date;
updatedAt: Date;
};
type ProductWithTimestamp = Product & Timestamped;
関数の型定義
関数の引数と戻り値の型
関数の引数と戻り値にも型を指定できます。
// 基本的な関数
function add(a: number, b: number): number {
return a + b;
}
const result = add(5, 3); // result は number 型
// アロー関数
const multiply = (a: number, b: number): number => a * b;
// オプショナル引数とデフォルト値
function greet(name: string, greeting: string = "こんにちは"): string {
return `${greeting}、${name}さん!`;
}
greet("田中"); // "こんにちは、田中さん!"
greet("田中", "おはよう"); // "おはよう、田中さん!"
// void型(戻り値なし)
function logMessage(message: string): void {
console.log(message);
}
コールバック関数の型
// 配列のforEachのコールバック
const numbers: number[] = [1, 2, 3];
numbers.forEach((num: number, index: number) => {
console.log(`${index}: ${num}`);
});
// 関数型の定義
type CalculateFunc = (a: number, b: number) => number;
const subtract: CalculateFunc = (a, b) => a - b;
const divide: CalculateFunc = (a, b) => a / b;
// 高階関数
function applyOperation(
a: number,
b: number,
operation: CalculateFunc
): number {
return operation(a, b);
}
applyOperation(10, 5, subtract); // 5
applyOperation(10, 5, divide); // 2
実践的なコード例
例1: API レスポンスの型定義
// APIレスポンスの型定義
interface ApiResponse<T> {
success: boolean;
data: T;
error?: string;
}
interface User {
id: number;
name: string;
email: string;
}
// API呼び出し関数
async function fetchUser(id: number): Promise<ApiResponse<User>> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
// 使用例
async function displayUser() {
const result = await fetchUser(1);
if (result.success) {
console.log(result.data.name); // 型安全にアクセス
console.log(result.data.email); // 自動補完も効く
} else {
console.error(result.error);
}
}
例2: フォームバリデーション
// フォームの型定義
interface RegistrationForm {
username: string;
email: string;
password: string;
confirmPassword: string;
}
// バリデーションエラーの型
type ValidationErrors = Partial<Record<keyof RegistrationForm, string>>;
// バリデーション関数
function validateForm(form: RegistrationForm): ValidationErrors {
const errors: ValidationErrors = {};
if (form.username.length < 3) {
errors.username = "ユーザー名は3文字以上必要です";
}
if (!form.email.includes("@")) {
errors.email = "有効なメールアドレスを入力してください";
}
if (form.password.length < 8) {
errors.password = "パスワードは8文字以上必要です";
}
if (form.password !== form.confirmPassword) {
errors.confirmPassword = "パスワードが一致しません";
}
return errors;
}
// 使用例
const formData: RegistrationForm = {
username: "taro",
email: "taro@example.com",
password: "password123",
confirmPassword: "password123"
};
const errors = validateForm(formData);
if (Object.keys(errors).length === 0) {
console.log("バリデーション成功!");
}
例3: ジェネリクスの活用
// 配列の最初の要素を取得(型安全)
function getFirst<T>(arr: T[]): T | undefined {
return arr[0];
}
const firstNumber = getFirst([1, 2, 3]); // number | undefined
const firstString = getFirst(["a", "b"]); // string | undefined
// 汎用的なデータストア
class DataStore<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
getAll(): T[] {
return [...this.items];
}
find(predicate: (item: T) => boolean): T | undefined {
return this.items.find(predicate);
}
}
// 使用例
const userStore = new DataStore<User>();
userStore.add({ id: 1, name: "田中", email: "tanaka@test.com" });
userStore.add({ id: 2, name: "鈴木", email: "suzuki@test.com" });
const user = userStore.find(u => u.id === 1); // User | undefined
始め方
npm install -g typescript でグローバルインストール
.ts拡張子でファイルを作成(例: app.ts)
tsc app.ts でJavaScriptに変換
tsc --init で tsconfig.json を生成
まとめ
TypeScriptは初期の学習コストはありますが、バグの早期発見、コードの可読性向上、強力なIDEサポートなど、それ以上のメリットがあります。特にチーム開発や長期プロジェクトでは必須と言えるでしょう。まずは既存のJavaScriptプロジェクトに少しずつ導入してみることをお勧めします。
テクノロジーで人々の日常をより便利に。AI、プログラミング、Web開発に関する情報を発信しています。