TypeScriptのclass

TypeScript

TypeScriptは静的型付けをサポートしており、classのプロパティやメソッドに型を指定できます。
これにより、型に基づく検査や補完が可能となり、コードの安全性と可読性が向上します。

本記事、TypeScriptのclassについて、JavaScriptのclassとの違いを中心にサンプルを交えながら説明していきます。

基本的なclass定義

TypeScriptでは、JavaScriptと同様にclassを定義できますが、プロパティやメソッドに型を指定できるという点がJavaScriptとは異なります。

JavaScriptのclassについては、こちらの記事をご確認ください。

TypeScript
class Person {
  name: string;
  age: number;

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

  greet(): void {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

const person = new Person('Alice', 30);
person.greet(); // 実行結果: Hello, my name is Alice and I am 30 years old.

JavaScriptのclassではプロパティをコンストラクタ内で宣言および初期化しますが、TypeScriptの場合、上記の例のとおり、Javaでいうメンバ変数(フィールド)のようにクラス直下に宣言します。

オプショナルプロパティ

classに、必須ではないプロパティを定義したい場合もあります。
そのような場合、プロパティ名の後に 「?」 を付けることでオプショナルプロパティとして定義できます。

オプショナルプロパティは、classだけでなく、インターフェイスや型エイリアス(type)、関数のパラメータとしても使用可能です。

TypeScript
class Person {
  name: string;
  age?: number;

  constructor(name: string, age?: number) {
    this.name = name;
    if (age !== undefined) {
      this.age = age;
    }
  }
}

// 👇オプショナルプロパティのageを指定せずインスタンス化している
const person = new Person("John");

アクセス修飾子

TypeScriptはアクセス修飾子(public、private、protected)をサポートしており、classのプロパティやメソッドのアクセス範囲(スコープ)を制御できます。

  • public:クラス内からアクセス可能
    • クラスのプロパティやメソッドにpublicを指定すると、そのプロパティやメソッドはクラスの内外からアクセスできます。また、デフォルトのアクセス修飾子であるため、明示的に指定しない場合もpublicとして扱われます。
  • private:クラス内からのみアクセス可能
    • privateを指定したプロパティやメソッドは、そのクラスの内部からのみアクセス可能です。クラスの外からは直接アクセスできません。
  • protected:クラス内およびサブクラスからアクセス可能
    • protectedを指定したプロパティやメソッドは、そのクラスとそのサブクラス(※1)からアクセス可能です。クラス外から直接アクセスすることはできませんが、サブクラス内からはアクセスできます。

アクセス修飾子は、プロパティおよびメソッドに適用できます。

※1:サブクラスとは、あるクラスを継承した子クラスのことを意味します。

「継承」についてはこちらの記事でご確認ください。

TypeScript
class Employee {
  public name: string;
  private salary: number;

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

  getSalary(): number {
    return this.salary;
  }
}

const employee = new Employee('Bob', 50000);
console.log(employee.name); // 実行結果: Bob
console.log(employee.salary); // エラー: 'salary' is private and only accessible within class 'Employee'.

デコレータ

TypeScriptはデコレータをサポートしており、クラスやプロパティ、メソッドに追加のメタデータや機能を付加できます。

デコレータは、特定の機能をモジュール化して再利用するのに便利です。

デコレータに関する情報は、非常に有用であり、詳細な説明が必要です。
種類も多くボリュームもあるため、本記事ではデコレータのシンプルな例を示すだけにとどめ、詳しい説明は別の記事に委ねます。

TypeScript
function readonly(target: any, key: string) {
  Object.defineProperty(target, key, {
    writable: false,
  });
}

class Car {
  @readonly
  brand: string;

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

const myCar = new Car('Toyota');
myCar.brand = 'Honda'; // エラー

多態性(ポリモーフィズム)

JavaScriptのclassと異なる点の最後は、インターフェイスや抽象クラスの使用により多態性(ポリモーフィズム)を実現できることです。

本記事ではclassについて説明しているため、抽象クラスによるポリモーフィズムを説明し、インターフェイスについては次回の記事で詳しく説明しています。

抽象クラス

TypeScriptは抽象クラス(abstract class)をサポートしており、直接インスタンス化できないクラスを定義できます。抽象クラスは、サブクラスで実装されるべき抽象メソッドを持つことができます。

抽象メソッドとは、実装(処理の中身)がプログラムされていないメソッドのことで、継承した子クラス(サブクラス)側で実装します。

TypeScript
abstract class Shape {
  // 👇メソッドのシグネチャだけ定義されており、実装がない
  abstract getArea(): number;
}

// 👇Shapeクラスを継承(拡張)したCircleクラスを定義
class Circle extends Shape {
  radius: number;

  constructor(radius: number) {
    super();
    this.radius = radius;
  }

  // 👇ここでメソッドが実装されている
  getArea(): number {
    return Math.PI * this.radius * this.radius;
  }
}

const circle = new Circle(5);
console.log(circle.getArea()); // 実行結果: 78.53981633974483

まとめ

TypeScriptのclassは、JavaScriptのclassにさらに多くの機能が追加されており、高い利便性を提供します。
型システム、アクセス修飾子、インターフェース、抽象クラス、デコレータなど、さまざまな機能を活用することで、より安全で効率的なコードを書くことができます。

ぜひ、TypeScriptのclassを使って、オブジェクト指向プログラミングを実践してみてください。


本記事についての質問、誤りの指摘、ご意見ご感想などありましたら、ぜひコメント頂ければ幸いです。

最後までお読みいただき、ありがとうございました。

コメント

タイトルとURLをコピーしました