JavaScriptでは、prototype
に適当に代入してあげればメソッドやプロパティの追加ができますが、
型という楽園を手に入れた TypeScript では簡単にはできません。
でもどうにかこうにかやる方法があったので、ググって色々試した結果を載せておきます。
ちなみに、現在作成中のこちらのソースで使っています。
やってみる
String
にメソッドを生やしたいと思います。
const methodName = "methodName"
が定義されている前提です。
ひとまずJSと同様に
String.prototype[methodName] = function (): void {} // => error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
当たり前にエラーです。
string
型でインデックスアクセスできませんよーとのことです。
インターフェースに定義してみる
interface String { [index: string]: Function; } String.prototype[methodName] = function (): void {} // => error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
インターフェースを定義してみましたが同じエラーが。 ちゃんと型定義ができていないみたいです。
ちなみに、index
をkey
とかmethodName
とかにしてもダメでした。
ならばprototype
に直接
interface String.prototype { [index: string]: Function; } String.prototype[methodName] = function (): void {} // => error TS1005: '{' expected.
そもそもクラスじゃないのでダメですね。
型に直接いれよう
interface string { [index: string]: Function; } String.prototype[methodName] = function (): void {} // => error TS2427: Interface name cannot be 'string'. // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
インターフェースにはプリミティブ型は直接定義できないみたいです。
prototype
がobject
型なので
interface Object { [index: string]: Function; } String.prototype[methodName] = function (): void {} // => error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
こちらもinterface String
と同じエラー。
とりあえず型のほうも試してみる
interface object { [index: string]: Function; } String.prototype[methodName] = function (): void {} // => error TS2427: Interface name cannot be 'object'. // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
やっぱりだめでした。
そして伝説へ……
(String.prototype as any)[methodName] = function (): void {}
これでコンパイルが通りました!
要するに、any
にキャストしてからメソッドを追加しています。
アディショナルタイム
interface String { [index: string]: Function; } (String.prototype as String)[methodName] = function (): void {} // => error TS2352: Type 'String' cannot be converted to type 'String'. // error TS2352: Type 'String' cannot be converted to type 'String'. Index signature is missing in type 'String'.
String
にしてみてもいけるかなーって思ったんですがダメでした……
所感
型を守りたかったんですが、最後はキャストで無理やりという結果に。
他にいいやり方があれば教えていただければ幸いです。