🐤

【TypeScript】アクセス修飾子 (access modifier)

に公開

はじめに

アクセス修飾子についてあらためてまとめてみようと思い、この記事を書いてます。

アクセス修飾子とは?

TypeScript の アクセス修飾子(access modifier) は、クラスのプロパティやメソッドに対して どこからアクセスできるか を制御する仕組みです。

オブジェクト指向プログラミングにおける「カプセル化(encapsulation)」の考え方に基づいており、クラス内部の状態を外部から勝手に変更されないように保護するために使われます。

TypeScript で使えるアクセス修飾子

1. public(デフォルト)

  • どこからでもアクセス可能
  • デフォルトの修飾子なので、指定しなくても public 扱いになる
class Animal {
  public name: string; // public
  constructor(name: string) {
    this.name = name;
  }
}

const dog = new Animal("Pochi");
console.log(dog.name); // OK

2. private

  • クラス 内部でのみアクセス可能
  • 外部やサブクラスからはアクセスできない
class Animal {
  private age: number;
  constructor(age: number) {
    this.age = age;
  }
}

const dog = new Animal(3);
// console.log(dog.age); // ❌ エラー: private プロパティにはアクセスできない

3. protected

  • クラス自身と サブクラスのみアクセス可能
  • 外部からはアクセスできない
class Animal {
  protected species: string;
  constructor(species: string) {
    this.species = species;
  }
}

class Dog extends Animal {
  showSpecies() {
    console.log(this.species); // OK
  }
}

const dog = new Dog("Canine");
// console.log(dog.species); // ❌ エラー: 外部からはアクセスできない

コンストラクタでのアクセス修飾子

TypeScript では、コンストラクタのパラメータに public / private / protected を付けると、以下のことが自動で行われます。

  • クラスのプロパティとして宣言される
  • コンストラクタ内で値が初期化される

これにより、クラス内で 明示的にプロパティを宣言して代入するコードを省略できます。

publicの例

class Person {
  constructor(public name: string, public age: number) {}
}

const alice = new Person("Alice", 30);
console.log(alice.name); // "Alice"
console.log(alice.age);  // 30

ポイント

  • 明示的に this.name = name と書く必要がない

private や protected の例

class Employee {
  constructor(private id: number, protected role: string) {}

  getId() {
    return this.id; // private プロパティにはクラス内からアクセス可能
  }

  getRole() {
    return this.role; // protected プロパティにはクラス内からアクセス可能
  }
}

const emp = new Employee(1, "Manager");
// console.log(emp.id);   // ❌ 外部からアクセス不可
// console.log(emp.role); // ❌ 外部からアクセス不可
console.log(emp.getId());   // 1
console.log(emp.getRole()); // "Manager"

アクセサ(getter/setter)との組み合わせ

TypeScript では、private プロパティと getter / setter を組み合わせることで、外部から安全にアクセス・操作できる仕組み を作ることができます。

  • private プロパティを直接変更させない
  • 条件付きで値を設定したり、加工して返したりできる

private と getter/setter で外部からの安全なアクセスを提供する例

例1. 年齢の制限付きアクセス

class User {
  private _age: number;

  constructor(age: number) {
    this._age = age;
  }

  // getter: プロパティを安全に参照
  get age() {
    return this._age;
  }

  // setter: 値を検証して設定
  set age(value: number) {
    if (value < 0) {
      throw new Error("Age must be positive");
    }
    this._age = value;
  }
}

const user = new User(25);
console.log(user.age); // 25

user.age = 30; // OK
console.log(user.age); // 30

// user.age = -5; // ❌ Error: Age must be positive

例2. 読み取り専用プロパティ

class Employee {
  private _id: number;

  constructor(id: number) {
    this._id = id;
  }

  // getter だけ用意 → 外部から変更できない
  get id() {
    return this._id;
  }
}

const emp = new Employee(101);
console.log(emp.id); // 101
// emp.id = 102; // ❌ 外部から変更不可

まとめ

  • public → 外部からも自由にアクセスできる
  • private → クラス内部専用
  • protected → クラス + サブクラス専用

Discussion