TypeScript classで型を限定したオブジェクト
やりたいこと。
TypeScript で型を限定したオブジェクトを作りたい。それにメソッドをつけたい。
ただのクラスはオブジェクトとして扱えない。コンパイルエラー
class StringObject {} let o = new StringObject(); o.foo = 'value-1'; // エラー o.bar = 'value-2'; // エラー o.baz = 'value-3'; // エラー
型を指定するとオブジョクトとして扱うことができる。
class StringObject { [k: string]: string } let o = new StringObject(); o.foo = 'value-1'; o.bar = 'value-2'; o.baz = 'value-3';
classで作ったオブジェクトにメソッドをもたせる。
- スタティックメソッドで実装する。
Object.keys(o)
などと同じような使い方になる。
class StringObject { [k: string]: string; constructor(o?: {[k: string]: string}) { for (let k in o) { this[k] = o[k]; } } public static values(o: StringObject): string[] { let a: string[] = []; for (let a in o) { a.push(o[k]); } return a; } } let o = new StringObject({foo : 'value-1', bar : 'value-2', baz : 'value-3'}); let a = StringObject.values(o); console.log(a); // [ 'value-1', 'value-2', 'value-3' ]
- オブジェクトの値の型を any で妥協すると
o.values();
のようにインスタンスメソッドで使える。
class StringObject { [k: string]: any; constructor(o: {[k: string]: any}) { for (let k in o) { this[k] = o[k]; } const dispatcher = { enumerable : false, configurable : false, writable : false, value : () => { let a: string[] = []; for (let k in this) { a.push(this[k]); } return a; } }; Object.defineProperty(this, 'values', dispatcher); } } let o = new StringObject(); o.foo = 'value-1'; o.bar = 'value-2'; o.baz = 'value-3'; // o.values = 'value-4'; // 上書きはできないのでエラー let a = o.values(); // 列挙しないように enumerable: false を設定したので values 自身は含まれない console.log(a); // [ 'value-1', 'value-2', 'value-3' ]