TypeScript

インターフェースと型エイリアス

TypeScript

interface、type、extends

interface

オブジェクト型の定義と拡張

interface.ts typescript
// 基本的な interface
interface User {
    id:       number;
    name:     string;
    email?:   string;    // オプショナル
    readonly createdAt: Date; // 読み取り専用
}

// 関数型
interface Formatter {
    (value: string, locale: string): string;
}

// インデックスシグネチャ
interface StringMap {
    [key: string]: string;
}

// 拡張(extends)
interface Admin extends User {
    role:        'admin' | 'superadmin';
    permissions: string[];
}

// 複数インターフェースの拡張
interface SuperAdmin extends Admin, Auditable {
    auditLog: string[];
}

// 宣言のマージ(同名interface は自動マージ)
interface Window { myPlugin: MyPlugin; }
interface Window { analytics: Analytics; }
// 両方の定義が有効

type エイリアス

型の別名定義と interface との違い

types.ts typescript
// type エイリアス
type UserId = number;
type UserName = string;

// オブジェクト型
type Point = { x: number; y: number; };

// Union型
type StringOrNumber = string | number;
type Status = 'active' | 'inactive' | 'pending';

// Intersection型(&)— 型の結合
type AdminUser = User & { role: 'admin' };
type WithTimestamp = { createdAt: Date; updatedAt: Date };
type UserRecord = User & WithTimestamp;

// type vs interface の主な違い
// interface: 宣言マージ可、クラスでimplements可
// type:      Union/Intersection型を直接表現可

// オブジェクト型には interface を使う(推奨)
interface UserDTO { id: number; name: string; }

// Union / Intersection / リテラル型には type を使う(推奨)
type ID = string | number;
type Theme = 'light' | 'dark';

クラスと型

implements、アクセス修飾子、抽象クラス

classes.ts typescript
interface Printable {
    print(): void;
}

class Document implements Printable {
    // アクセス修飾子
    public    title:   string;    // どこからでもアクセス可(デフォルト)
    private   content: string;    // クラス内のみ
    protected author:  string;    // クラスとサブクラス
    readonly  id:      number;    // 変更不可

    // コンストラクタ短縮記法
    constructor(
        public name: string,
        private secret: string,
    ) {}

    print(): void {
        console.log(this.title);
    }
}

// 抽象クラス
abstract class Shape {
    abstract area(): number; // サブクラスで実装必須

    describe(): string {
        return `面積: ${this.area()}`; // 共通実装
    }
}

class Circle extends Shape {
    constructor(private radius: number) { super(); }
    area(): number { return Math.PI * this.radius ** 2; }
}