TypeScriptでクラス定数を定義する:4つの方法とそれぞれのメリット・デメリット
TypeScriptにおけるクラス定数の実装方法
const キーワード
コード例
class MyClass {
static readonly PI = 3.14;
static readonly MAX_SIZE = 100;
}
利点
- シンプルで分かりやすい
- 他のクラスメンバーと同様にアクセスできる
欠点
- 型推論が働かない
- 値の変更ができない
enum
enum Color {
Red,
Green,
Blue
}
class MyClass {
static readonly PRIMARY_COLOR = Color.Red;
static readonly SECONDARY_COLOR = Color.Green;
}
- 型安全性が高い
- 値のリストを簡単に定義できる
- 数値リテラル以外の値を定義できない
ネームスペース
namespace MyConstants {
export const PI = 3.14;
export const MAX_SIZE = 100;
}
class MyClass {
static readonly PRIMARY_COLOR = MyConstants.PI;
static readonly SECONDARY_COLOR = MyConstants.MAX_SIZE;
}
- 関連する定数をまとめて定義できる
- 名前空間スコープによって衝突を回避できる
- 少し冗長なコードになる
クラスプロパティ
class MyClass {
private static readonly _pi = 3.14;
private static readonly _maxSize = 100;
static get PI(): number {
return this._pi;
}
static get MAX_SIZE(): number {
return this._maxSize;
}
}
- プライベートな定数を定義できる
- ゲッター/セッターを使って値の制御ができる
- コード量が少し増える
どの方法を選ぶべきかは、状況によって異なります。以下のような点を考慮しましょう。
- 定数の型
- 定数の変更可能性
- コードの簡潔性
- 読みやすさ
例えば、単純な数値リテラルを定義する場合は、const
キーワードを使うのが最も簡単です。一方、複雑な値や型安全性が必要な場合は、enum
やクラスプロパティを使うのが良いでしょう。
TypeScriptでクラス定数を定義するには、いくつかの方法があります。それぞれの方法の利点と欠点を理解して、状況に合わせて適切な方法を選びましょう。
// 1. const キーワード
class MyClass1 {
static readonly PI = 3.14;
static readonly MAX_SIZE = 100;
constructor() {
console.log(`PI: ${MyClass1.PI}`);
console.log(`MAX_SIZE: ${MyClass1.MAX_SIZE}`);
}
}
const myClass1 = new MyClass1();
// 2. enum
enum Color {
Red,
Green,
Blue
}
class MyClass2 {
static readonly PRIMARY_COLOR = Color.Red;
static readonly SECONDARY_COLOR = Color.Green;
constructor() {
console.log(`PRIMARY_COLOR: ${MyClass2.PRIMARY_COLOR}`);
console.log(`SECONDARY_COLOR: ${MyClass2.SECONDARY_COLOR}`);
}
}
const myClass2 = new MyClass2();
// 3. ネームスペース
namespace MyConstants {
export const PI = 3.14;
export const MAX_SIZE = 100;
}
class MyClass3 {
static readonly PRIMARY_COLOR = MyConstants.PI;
static readonly SECONDARY_COLOR = MyConstants.MAX_SIZE;
constructor() {
console.log(`PRIMARY_COLOR: ${MyClass3.PRIMARY_COLOR}`);
console.log(`SECONDARY_COLOR: ${MyClass3.SECONDARY_COLOR}`);
}
}
const myClass3 = new MyClass3();
// 4. クラスプロパティ
class MyClass4 {
private static readonly _pi = 3.14;
private static readonly _maxSize = 100;
static get PI(): number {
return this._pi;
}
static get MAX_SIZE(): number {
return this._maxSize;
}
constructor() {
console.log(`PI: ${MyClass4.PI}`);
console.log(`MAX_SIZE: ${MyClass4.MAX_SIZE}`);
}
}
const myClass4 = new MyClass4();
このコードを実行すると、以下のような出力になります。
PI: 3.14
MAX_SIZE: 100
PRIMARY_COLOR: 0
SECONDARY_COLOR: 1
PRIMARY_COLOR: 3.14
SECONDARY_COLOR: 100
PI: 3.14
MAX_SIZE: 100
readonly 修飾子
class MyClass {
readonly PI = 3.14;
readonly MAX_SIZE = 100;
constructor() {
console.log(`PI: ${this.PI}`);
console.log(`MAX_SIZE: ${this.MAX_SIZE}`);
}
}
const myClass = new MyClass();
- オブジェクト生成後に値を変更できない
- コードが簡潔になる
- 静的メンバーには使用できない
private フィールドとゲッター
class MyClass {
private _pi = 3.14;
private _maxSize = 100;
get PI(): number {
return this._pi;
}
get MAX_SIZE(): number {
return this._maxSize;
}
constructor() {
console.log(`PI: ${this.PI}`);
console.log(`MAX_SIZE: ${this.MAX_SIZE}`);
}
}
const myClass = new MyClass();
デコレータ
function readonly(target: any, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
writable: false,
configurable: false,
});
}
class MyClass {
@readonly
PI = 3.14;
@readonly
MAX_SIZE = 100;
constructor() {
console.log(`PI: ${this.PI}`);
console.log(`MAX_SIZE: ${this.MAX_SIZE}`);
}
}
const myClass = new MyClass();
- コードをより簡潔に記述できる
- メタデータを利用した高度な機能を実現できる
- デコレータの仕組みを理解する必要がある
- 古いブラウザではサポートされていない
typescript class-constants