TypeScriptとは?JavaScriptとの違いを徹底解説
TypeScriptはMicrosoftが開発したJavaScriptのスーパーセットです。2026年現在、フロントエンド開発では事実上の標準となっており、Next.js・Vue.js・Angularなど主要フレームワークが採用しています。
JavaScriptとの最大の違いは静的型付けです。コードを実行する前にバグを発見でき、大規模プロジェクトでの開発効率が劇的に向上します。
TypeScriptのインストールと環境構築
# Node.jsがインストールされていることを確認
node -v # v20以上推奨
# TypeScriptをグローバルインストール
npm install -g typescript
# バージョン確認
tsc -v # Version 5.x
# プロジェクト初期化
mkdir my-ts-project && cd my-ts-project
npm init -y
npm install --save-dev typescript @types/node
npx tsc --init
TypeScriptの基本型システム
TypeScriptの型システムは非常に強力です。基本的な型から始めましょう。
プリミティブ型
// 基本的な型宣言
let name: string = "Tech Athletes";
let age: number = 25;
let isActive: boolean = true;
let data: null = null;
let value: undefined = undefined;
// 型推論(明示的な型宣言なしでも型が決まる)
let message = "Hello TypeScript"; // string型として推論される
let count = 42; // number型として推論される
// anyとunknown(なるべく避けるべき)
let anything: any = "whatever";
let safeAny: unknown = "safer";
配列とタプル型
// 配列型
const numbers: number[] = [1, 2, 3, 4, 5];
const strings: Array<string> = ["React", "Vue", "Angular"];
// タプル型(固定長・固定型の配列)
let coordinate: [number, number] = [35.6762, 139.6503];
let userInfo: [string, number, boolean] = ["kasata", 30, true];
// 読み取り専用配列
const readonly_arr: readonly string[] = ["TypeScript", "JavaScript"];
// readonly_arr.push("Python"); // エラー!
オブジェクト型とインターフェース
// インターフェース定義(推奨)
interface User {
id: number;
name: string;
email: string;
age?: number; // オプショナルプロパティ
readonly createdAt: Date; // 読み取り専用
}
// インターフェースの実装
const user: User = {
id: 1,
name: "テック太郎",
email: "tech@example.com",
createdAt: new Date()
};
// インターフェースの拡張
interface AdminUser extends User {
role: "admin" | "superadmin";
permissions: string[];
}
// 型エイリアス(typeキーワード)
type Point = {
x: number;
y: number;
};
type StringOrNumber = string | number; // ユニオン型
ジェネリクス(Generics)完全解説
ジェネリクスはTypeScriptの最も強力な機能の一つです。型を引数として渡すことで、再利用可能な型安全なコードを書けます。
// 基本的なジェネリクス関数
function identity<T>(arg: T): T {
return arg;
}
const str = identity<string>("Hello"); // string型
const num = identity(42); // number型(型推論)
// ジェネリクスを使ったAPIレスポンス型
interface ApiResponse<T> {
data: T;
status: number;
message: string;
timestamp: Date;
}
interface Article {
id: number;
title: string;
content: string;
author: string;
}
// 型安全なAPIレスポンス
const articleResponse: ApiResponse<Article> = {
data: {
id: 1,
title: "TypeScript完全ガイド",
content: "...",
author: "kasata"
},
status: 200,
message: "Success",
timestamp: new Date()
};
// 制約付きジェネリクス
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: "Tech", age: 25, email: "tech@example.com" };
const userName = getProperty(user, "name"); // OK
// const invalid = getProperty(user, "invalid"); // エラー!
TypeScriptのユーティリティ型
TypeScriptには便利な組み込みユーティリティ型があります。これを使いこなすと開発効率が大幅に上がります。
interface User {
id: number;
name: string;
email: string;
password: string;
age: number;
}
// Partial: 全プロパティをオプショナルに
type PartialUser = Partial<User>;
// { id?: number; name?: string; ... }
// Required: 全プロパティを必須に
type RequiredUser = Required<PartialUser>;
// Pick: 特定プロパティのみ選択
type UserProfile = Pick<User, "id" | "name" | "email">;
// Omit: 特定プロパティを除外
type SafeUser = Omit<User, "password">;
// Readonly: 全プロパティを読み取り専用に
type ImmutableUser = Readonly<User>;
// Record: キーと値の型マッピング
type UserMap = Record<string, User>;
// Exclude / Extract: ユニオン型の操作
type Status = "active" | "inactive" | "banned";
type ActiveStatus = Extract<Status, "active">; // "active"
type NonActive = Exclude<Status, "active">; // "inactive" | "banned"
// ReturnType: 関数の戻り値型を取得
function getUser() { return { id: 1, name: "Tech" }; }
type UserReturn = ReturnType<typeof getUser>; // { id: number; name: string; }
デコレーター(Decorators)実践ガイド
デコレーターはクラス、メソッド、プロパティに追加のメタデータや機能を付与する構文です。Angular・NestJSなどで広く使用されています。
// tsconfig.jsonでexperimentalDecoratorsを有効化
// "experimentalDecorators": true
// クラスデコレーター
function Sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@Sealed
class BugReport {
type = "report";
title: string;
constructor(t: string) { this.title = t; }
}
// メソッドデコレーター(ログ出力の例)
function Log(target: any, key: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${key} with`, args);
const result = original.apply(this, args);
console.log(`${key} returned`, result);
return result;
};
return descriptor;
}
class Calculator {
@Log
add(a: number, b: number): number {
return a + b;
}
}
TypeScript + React実践パターン
ReactとTypeScriptを組み合わせた実践的なコードパターンを紹介します。
import React, { useState, useEffect, FC } from 'react';
// コンポーネントのProps型定義
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary' | 'danger';
disabled?: boolean;
children?: React.ReactNode;
}
// 関数コンポーネントの型付け
const Button: FC<ButtonProps> = ({
label,
onClick,
variant = 'primary',
disabled = false,
children
}) => {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
disabled={disabled}
>
{children || label}
</button>
);
};
// カスタムフックの型付け
interface FetchState<T> {
data: T | null;
loading: boolean;
error: string | null;
}
function useFetch<T>(url: string): FetchState<T> {
const [state, setState] = useState<FetchState<T>>({
data: null,
loading: true,
error: null
});
useEffect(() => {
fetch(url)
.then(res => res.json())
.then((data: T) => setState({ data, loading: false, error: null }))
.catch(err => setState({ data: null, loading: false, error: err.message }));
}, [url]);
return state;
}
TypeScript設定ファイル(tsconfig.json)最適化
本番環境向けのtsconfig.jsonの推奨設定を紹介します。
{
"compilerOptions": {
"target": "ES2022", // 出力するJavaScriptのバージョン
"module": "CommonJS", // モジュールシステム
"lib": ["ES2022", "DOM"], // 使用するライブラリ
"outDir": "./dist", // 出力ディレクトリ
"rootDir": "./src", // ソースディレクトリ
"strict": true, // 厳格モード(推奨)
"noImplicitAny": true, // any型の暗黙的使用を禁止
"strictNullChecks": true, // null/undefinedチェックを厳格に
"noUnusedLocals": true, // 未使用変数をエラーに
"noUnusedParameters": true, // 未使用パラメーターをエラーに
"exactOptionalPropertyTypes": true, // オプショナルプロパティの厳格化
"noImplicitReturns": true, // 全コードパスでreturn必須
"esModuleInterop": true, // CommonJS互換
"skipLibCheck": true, // 型定義ファイルのチェックをスキップ
"forceConsistentCasingInFileNames": true,
"declaration": true, // .d.tsファイル生成
"sourceMap": true // デバッグ用ソースマップ
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
まとめ:TypeScript習得のロードマップ
TypeScriptの習得には段階があります。まず基本型から始め、インターフェース・ジェネリクスと進め、最終的にはデコレーター・高度な型操作まで習得を目指しましょう。
- 初級(1〜2週間):基本型・インターフェース・型エイリアス
- 中級(1〜2ヶ月):ジェネリクス・ユーティリティ型・非同期処理
- 上級(3〜6ヶ月):条件型・マップ型・デコレーター・型レベルプログラミング
TypeScriptをマスターすることで、年収アップや転職にも有利に働きます。ぜひ日々の開発に取り入れてみてください。