SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ますます便利になるTypeScript! バージョン3からの変更点と総まとめ

プライベート構文やアクセサなど、TypeScriptのクラス構文に関する変更点を解説

ますます便利になるTypeScript! バージョン3からの変更点と総まとめ 第5回

  • X ポスト
  • このエントリーをはてなブックマークに追加

アクセサに関する新しい仕組みとは

 次に紹介するのは、アクセサに関する新しい仕組みです。

TypeScriptのアクセサ

 アクセサは、JavaScriptのクラス構文にもある仕組みなので、当たり前のように使っている方も多いでしょう。本稿でも、プライベートアクセサの例として、#bmiゲッタをリスト4で紹介しています。#bmiはゲッタのみでしたが、例えば、#nameフィールドのアクセサとして、nameのゲッタとセッタの両方を定義するとなると、リスト8のようなコードになります。

リスト8:アクセサによるnameプロパティの定義
class BMIData {
  #name: string;
  :
  get name(): string {  // (1)
    return this.#name;
  }
  set name(value: string) {  // (2)
    this.#name = value;
  }
}

 ここで注目するのは、リスト8の(1)と(2)の型指定です。プライベートな#bmiゲッタ同様に、TypeScriptらしく、ゲッタ、セッタの両方に型としてstringが指定されています。これにより、nameプロパティはstringとして働くようになります。

型指定に関する変更点

 実は、同名のプロパティをセッタとゲッタの両方で定義する場合、それぞれの型として同じものを指定する必要がありました。この仕組みがバージョン4.3で変更になり、それぞれ別々の型指定が行えるようになりました。この仕組みを利用すると、例えば、リスト9のようなweightプロパティの定義が可能となります。

リスト9:別々の型を指定したweightプロパティ
class BMIData {
  :
  #weight: number;
  :
  get weight(): string {  // (1)
    return `体重${this.#weight}kg`;
  }
  set weight(value: number) {  // (2)
    this.#weight = value;
  }
}

 リスト9では、(2)にあるように、weightプロパティのセッタはnumber型として定義しています。そのため、weightプロパティに値を代入する場合は、数値以外は受け付けません。一方で、(1)にあるように、weightプロパティにアクセスしてデータを取得した場合、「体重〇〇kg」という文字列表現が返ってくることになり、データ型はstringです。

 実は、バージョン4.3でこの別々の型指定の仕組みが導入された時点では、リスト9のコードはエラーとなっていました。なぜなら、ゲッタのデータ型は必ずセッタに含まれている、つまり、セッタのデータ型のサブタイプである必要があったからです。そのため、リスト9のコードを実現するためには、セッタの定義は以下のようにstring型を含めておく必要がありました。

set weight(value: number | string) {

 これが、バージョン5.1で変更になり、セッタとゲッタの型が完全に独立して指定できるようになりました。リスト9のコードが成立するのは、この変更のおかげです。

オートアクセサとは

 アクセサ関連で本節の最後に紹介するのは、バージョン4.9で導入されたオートアクセサという機能です。これは、リスト10のように、フィールドにaccessorキーワードを付与することで、自動的にフィールドがプライベートになり、代わりに同名のアクセサが自動生成される仕組みです。

リスト10:オートアクセサのコード例
class BMIData {
  accessor name: string;
  :
}

 上記コードは、イメージ的にリスト11と同等の内容になります。

リスト11:オートアクセサの実装イメージ
class BMIData {
  #name_accessor_storage: string;
  get name(): string {
    return this.#name_accessor_storage;
  }
  set name(value: string) {
    this.#name_accessor_storage = value;
  }
}

 このaccessorキーワードによるオートアクセサ機能は、ECMAScriptで提案されている機能であり、それをTypeScriptが先行導入したものです。ただし、原稿執筆時点では、ECMAScriptではまだステージ1の段階であり、まだまだ発展途上です。そのせいか、TypeScriptでもまだまだ不完全な状態です。例えば、readonlyキーワードが使えません。同じく、フィールドをプライベートにしてゲッタのみを定義することで、読み取り専用(readonly)プロパティが定義できますが、それもできません。ゲッタ、セッタそれぞれのカスタマイズもできません。本家のECMAScriptも含めて、この辺りの今後の発展に期待したいと思います。

staticブロックと

 最後に紹介するのは、staticブロックです。これは、例えば、リスト12のようなコードです。

リスト12:staticブロックの例
class Members {
  static count: number = 0;  // (1)
  static {  // (2)
    if(checkStatus()) {  // (3)
      Members.count = getCurrentMemberCount();  // (4)
    }
  }
}

 リスト12の(2)がstaticブロックです。この仕組みは、ES2022で導入されたものであり、TypeScriptではバージョン4.4で先行導入されています。このstaticブロック内では、(1)のようなstatic変数の初期化処理が可能となります。

 リスト12の初期化処理はひとつの例であり、(3)で関数checkStatus()を実行し、その結果に応じて、(4)のようにstatic変数であるcountの値をgetCurrentMemberCount()関数の戻り値の値とするような処理としています。

 このように、ある条件に応じてstatic変数の値を変更するようなコードを記述しようとすると、コンストラクタではできません。なぜなら、コンストラクタはクラスがnewする際、すなわち、オブジェクトが生成される際に実行される処理であるため、オブジェクト横断で利用されるstatic変数の初期化処理はできないからです。これが、staticブロックが必要な理由です。

まとめ

 TypeScriptのバージョン5.2までに導入された新機能をテーマごとに紹介する本連載の第5回目はいかがでしたでしょうか。

 今回は、クラス構文に関する新しい仕組みを紹介しました。次回は、バージョン5.2までの新機能を紹介する最後のテーマとして「デコレータ」を紹介します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ますます便利になるTypeScript! バージョン3からの変更点と総まとめ連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook<個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/19501 2024/05/30 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング