TypeScriptでクラスを型安全に書く:public, private, readonlyの使い分け

オブジェクト指向プログラミングにおける「クラス」は、コードの構造化と再利用性を高める重要な要素です。TypeScriptでは、public、private、readonlyといったアクセス修飾子を使うことで、より堅牢で型安全なクラス設計が可能になります。本記事では、それぞれの修飾子の役割と具体的な使い分けについて、実践的なコード例とともに解説します。

public:外部から自由にアクセスさせたい場合に使う

public はデフォルトの修飾子で、明示しなくてもプロパティやメソッドは public として扱われます。外部からアクセス・変更可能なメンバーに使用します。

class User {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }

    public greet(): void {
        console.log(`Hello, ${this.name}`);
    }
}

const user = new User("Taro");
user.name = "Jiro"; // アクセス・変更可能
user.greet();       // 呼び出し可能

使いどころ

  • クラスの利用者が自由に値を設定したい場合
  • 外部に公開するAPIやメソッド

private:内部実装を隠蔽し、外部からの誤操作を防ぐ

private はクラス外からアクセスできないようにする修飾子です。内部ロジックや状態を守り、意図しない変更を防止します。

class Counter {
    private count: number = 0;

    public increment(): void {
        this.count++;
    }

    public getCount(): number {
        return this.count;
    }
}

const counter = new Counter();
counter.increment();
console.log(counter.getCount()); // 1
// counter.count = 100; // エラー:'count' は private です

使いどころ

  • 内部状態(例:ID、カウント、フラグ)の隠蔽
  • 外部から触らせたくないロジックやプロパティの保護

readonly:初期化後に変更させない不変データの表現

readonly は一度だけ代入可能で、それ以降の変更を禁止します。コンストラクタ内では代入可能です。

class Product {
    public readonly id: string;
    public name: string;

    constructor(id: string, name: string) {
        this.id = id;
        this.name = name;
    }
}

const p = new Product("p001", "りんご");
p.name = "バナナ";
// p.id = "p002"; // エラー:readonly プロパティの変更は不可

使いどころ

  • 不変なIDやシステム固有値の保持
  • データ整合性を維持したいフィールド

複合使用の例:堅牢なクラス設計

以下は、publicprivatereadonly を組み合わせた実用例です。

class BankAccount {
    private readonly id: string;
    private balance: number;

    constructor(id: string, initialBalance: number) {
        this.id = id;
        this.balance = initialBalance;
    }

    public deposit(amount: number): void {
        if (amount <= 0) throw new Error("無効な金額です");
        this.balance += amount;
    }

    public withdraw(amount: number): void {
        if (amount > this.balance) throw new Error("残高不足です");
        this.balance -= amount;
    }

    public getBalance(): number {
        return this.balance;
    }

    public getId(): string {
        return this.id;
    }
}
  • idreadonly + private ⇒ 外部から変更不可・取得のみ
  • balanceprivate ⇒ 外部から直接操作させない
  • deposit, withdrawpublic ⇒ 公開APIとして使用

まとめ:アクセス修飾子でクラスを型安全に設計しよう

アクセス修飾子を適切に使い分けることで、クラスの安全性と可読性が大きく向上します。

  • public:利用者に開放したいプロパティ・メソッド
  • private:外部から触らせたくない内部ロジックや状態
  • readonly:一度設定したら変わらない値の表現

TypeScriptの強力な型システムと組み合わせることで、より堅牢で意図の明確なコードを記述できるようになります。ぜひ、自分のプロジェクトでも積極的に活用してみてください。

Contact

ウェブサイトの制作や運用に関わる
お悩みやご相談
お気軽にお問い合わせ下さい

ウェブサイトと一口に言っても、企業サイトやECサイト、ブログ、SNSなど、その“カタチ”は目的に応じてさまざまであり、構築方法や使用する技術も大きく異なります。株式会社コナックスでは、お客様のご要望やブランドの個性を丁寧に汲み取り、最適なウェブサイトの“カタチ”をご提案いたします。

デザイン、ユーザビリティ、SEO対策はもちろん、コンテンツ制作やマーケティング戦略に至るまで、あらゆるフェーズでお客様のビジネスに寄り添い、成果につながるウェブサイトづくりをサポートいたします。私たちは、ウェブサイトの公開をゴールではなくスタートと捉え、お客様のビジネスの成功に向けて共に伴走してまいります。