TypeScript
TypeScript
概要(サマリー)
TypeScriptとは、JavaScriptに「型」の仕組みを追加したプログラミング言語のことである。Microsoftが開発し、2012年に公開された。TypeScriptで書いたコードは最終的にJavaScriptに変換(トランスパイル)されて動作するため、JavaScriptが動く環境ならどこでも使える。「型」とは変数に入れるデータの種類(数値・文字列・真偽値など)を事前に決めておく仕組みで、これによりコーディング中にバグを早期発見しやすくなる。大規模なプロジェクトや複数人での開発で特に力を発揮する。
詳細解説
「型」とは何か
JavaScriptでは変数にどんな種類のデータでも代入できる。
// JavaScriptの場合:型の縛りがない
let score = 100;
score = 'とても良い'; // 文字列を代入してもエラーにならない
これは柔軟だが、意図しないデータ型が混入してもコードを実行するまで気づけない。TypeScriptでは型を明示することで、コーディング中(エディタ上)に問題を検出できる。
// TypeScriptの場合:型を指定する
let score: number = 100;
score = 'とても良い'; // エラー!numberにstringは代入できない
TypeScriptの主な記法
// 変数の型指定
const name: string = '田中';
const age: number = 25;
const isActive: boolean = true;
// 関数の引数と戻り値の型指定
function add(a: number, b: number): number {
return a + b;
}
// オブジェクトの型定義(interface)
interface User {
name: string;
age: number;
email?: string; // ?は省略可能を意味する
}
const user: User = { name: '田中', age: 25 };
type(タイプエイリアス)とinterfaceの違い
TypeScriptでオブジェクトの型を定義する方法には interface と type の2つがある。
// interface:オブジェクトの構造定義に向いている
interface Point {
x: number;
y: number;
}
// type:ユニオン型(いずれかの値)や文字列リテラル型に使いやすい
type Status = 'active' | 'inactive' | 'pending';
let userStatus: Status = 'active';
// userStatus = 'deleted'; // エラー!定義外の値は代入不可
実用的には「オブジェクトの型定義には interface、それ以外(文字列の制約など)には type」を基本にすると混乱が少ない。どちらを使っても動作するケースも多いが、プロジェクト内でルールを統一することが大切だ。
ユーティリティ型
TypeScriptには既存の型を変形する便利な「ユーティリティ型」が組み込まれている。
interface User {
name: string;
age: number;
email: string;
}
// Partial<T>:全プロパティを省略可能にする
// 更新フォームで「変更する項目だけ指定」したいときに便利
const update: Partial<User> = { name: '鈴木' }; // ageもemailも省略OK
// Readonly<T>:全プロパティを読み取り専用にする
const admin: Readonly<User> = { name: '田中', age: 30, email: 'a@b.com' };
// admin.name = '鈴木'; // エラー!変更不可
// Pick<T, K>:特定のプロパティだけを取り出す
type UserPreview = Pick<User, 'name' | 'age'>;
// emailなしのUser型として扱える
これらは「すでにある型を少し変えて使い回す」ための仕組みだ。同じ構造を何度も書き直す手間が省けるうえ、変更漏れのリスクも減る。
ジェネリクス
ジェネリクス(<T>)は、型をパラメータとして受け取る仕組みだ。「どんな型にも対応する、再利用可能な関数・型」を作るときに使う。
// <T>で「任意の型」を表す
function getFirst<T>(arr: T[]): T {
return arr[0];
}
const num = getFirst([1, 2, 3]); // numberと推論される
const str = getFirst(['a', 'b', 'c']); // stringと推論される
最初は難しく感じるが、「型を後から決める仕組み」というイメージを持っておくと理解しやすい。配列操作・非同期処理・APIレスポンスの型付けでよく登場する。
JavaScriptとの関係
TypeScriptはJavaScriptの「上位互換」だ。有効なJavaScriptコードはそのままTypeScriptとしても動作する。つまり、既存のJavaScriptプロジェクトに少しずつTypeScriptを導入していくことも可能だ。
TypeScriptはそのままブラウザやNode.jsで実行できないため、tsc(TypeScript Compiler)やVite・esbuildなどのツールでJavaScriptにコンパイルしてから使う。
AIコーディングとTypeScriptの関係
AIはTypeScriptの型定義を生成するのが得意だ。「このAPIのレスポンスの型を定義して」と依頼すると、interface や type を使った型定義を自動で生成してくれる。
ただし、AIが生成するコードには型安全性を犠牲にした any 型(何でも入れられる型)が混入することがある。any を多用するとTypeScriptの型チェックが無効化され、JavaScriptとほぼ同じ状態になる。指示の中に「any は使わず適切な型を定義してください」と明示しておくとよい。
また、interface を先に設計してからコードを依頼する方法が効果的だ。「この User 型の配列を受け取り、名前だけを返す関数を作って」のように型情報を先に伝えると、意図に沿ったコードが生成されやすい。
よくある勘違い
TypeScriptを使えばバグはなくなる?
そうではない。TypeScriptの型チェックは型に関するバグを減らすが、ロジックの誤り(計算間違いや仕様の取り違え)は検出できない。型安全性はバグ予防の一手段であり、テストやコードレビューの代替にはならない。
JavaScriptを知らなくてもTypeScriptを学べる?
難しい。TypeScriptはJavaScriptの上に型を追加したものであり、JavaScriptの理解が前提になる。エラーメッセージもJavaScriptの知識がないと読み解けないことが多い。まずJavaScriptを学ぶことを強く推奨する。
TypeScriptはJavaScriptより遅い?
実行速度は変わらない。TypeScriptは最終的にJavaScriptに変換されて動作するため、実行時の速度差はない。コンパイル(変換)の時間がビルド工程で加わるだけだ。
any 型を使えばとりあえず動く?
動くが、推奨されない。any はTypeScriptの型チェックを無効化する型で、「どんな型の値でも許可する」という意味になる。any を多用すると型定義をしていないJavaScriptと実質同じ状態になり、TypeScriptを採用した意義が薄れる。どうしても型が決まらない場合は unknown 型を検討するか、AIに適切な型の推測を依頼しよう。
より詳しくAIに聞いてみよう
- TypeScriptとは何か、JavaScriptとの違いを初心者でもわかるように説明してください。
- TypeScriptの型定義(interface・type)の使い方と違いを教えてください。
- TypeScriptのユーティリティ型(Partial・Readonly・Pick・Omit)の使い方を具体例つきで教えてください。
- ジェネリクス(
<T>)の基本的な使い方と、どんな場面で便利かを教えてください。 - AIコーディングでTypeScriptを使う場合に、
anyを避けた適切な型定義を生成してもらうコツを教えてください。