メインコンテンツまでスキップ

コンパニオンオブジェクトパターン

TypeScriptでは値と型に同名を与えてその両方を区別なく使うことができるテクニックがあります。これをコンパニオンオブジェクトと呼びます。
これは、クラスを作るほどでもなけどそれっぽいファクトリーメソッドとオブジェクトが欲しいときに重宝します。

コンパニオンオブジェクト (Companion Object)

次の例は長方形 (Rectangle) を作成するためのメソッドfrom()をもつオブジェクトRectangleとその生成されるオブジェクトの型Rectangleです。これらの名称は衝突することなく定義ができ、外部から呼び出したときは同名で使用できます。

次の型と値 (ファクトリーメソッドを持つオブジェクト) は同じファイルrectangle.tsに存在するとします。

ts
export type Rectangle = {
height: number;
width: number;
};
 
export const Rectangle = {
from(height: number, width: number): Rectangle {
return {
height,
width,
};
},
};
ts
export type Rectangle = {
height: number;
width: number;
};
 
export const Rectangle = {
from(height: number, width: number): Rectangle {
return {
height,
width,
};
},
};

値も型も同名で定義します。これを外部から import してみます。

ts
import { Rectangle } from "./rectangle";
 
const rec: Rectangle = Rectangle.from(1, 3);
 
console.log(rec.height);
1
console.log(rec.width);
3
ts
import { Rectangle } from "./rectangle";
 
const rec: Rectangle = Rectangle.from(1, 3);
 
console.log(rec.height);
1
console.log(rec.width);
3

このように import の部分はRectangleのみとなり見通しもつきやすいという特徴があります。ちなみにRectangle.from()のRectangleが値でありconst rec: RectangleのRectangleが型です。このようにTypeScriptでは同名の値と型を同時に使うことができます。