普段からプログラミングをしている人だと後から設定変更をすることを考慮したり、可読性を意識して、定数にも名前をつけることがあると思います。今回は、弊社の若手エンジニアからJavaのような定数クラスをTypescriptで定義したいという話から何パターンか考えてみたので、そのときの内容を共有しようと思います。今回の例では、WEBサイト用の専用のカラー定義をTypescript(Javascript)で定義するケースを例としてサンプルコードを示そうと思います。

  • 名前空間を利用する方法
  • readonly、staticを利用する方法
  • getアクセサを利用する方法

1.名前空間を利用する方法

厳密には、クラスでは無いのですが、クラスのように扱う方法です。

下記のようにモジュールを作成します。clors.tsとします。

/** 専用の名前空間を定義 */
namespace Colors {
  // 専用の赤を定義
  export const HOGE_RED = '#FF3333';
}

export default Colors

利用するコードは、

import Colors from 'colors'

// このような形で利用する。
console.log(Colors.HOGE_RED)

2.readonly、staticを利用する

今回は、クラスを生成してそれを利用する方法です。

/** 専用のColorsクラスを定義 */
class Colors {
  // 専用の赤を定義
  static readonly HOGE_RED = '#FF3333';
}

export default Colors

利用するコードは同じなので、省略します。

注意が必要なのですが、HOGE_REDは、classのプロパティと呼ばれるもので、プロパティに対しては、constを利用することができません。実際にコードを書いてみると1248: A class member cannot have the 'const' keyword.という形でエラーが表示されると思います。

プロパティが読み取り専用の場合には、Readonlyを利用します。

constとreadonlyの違い

Typescriptでは、constreadonlyともに読み込み専用・変更出来ないということを表すために利用します。違いは、プロパティには、readonly、変数には、constを使用します。

Typescriptでは、interfaceもプロパティを持つことが許されているので、classやintefaceなどのプロパティが変更されないことを示すために、readonlyをつけることで読み取り専用=定数として表します。

3. getアクセサを使うパターン

Typescriptのgetアクセサを利用するパターンも示しておきます。

/** 専用のColorsクラスを定義 */
class Colors {
  // 専用の赤を返すgetを実装する
  static get HOGE_RED() {
    return '#FF3333'
  }
}

export default Colors

このパターンは、getアクセサを利用して、‘プロパティのような’挙動をさせている感じです。少し違和感がある感じがします。

おわりに

実際に利用するとなると、パターン1、パターン2あたりが多いと思います。getアクセサを利用するパターンは、違和感がありますが、メンバー同士で色々な意見が出来てきたので、せっかくなので紹介しました。