TypeScriptでArray<T>
を継承してある型専用のクラスを作ったとする。
そのクラスはnewすれば、そのクラスに生えているメソッドを使うことができる。
class StringArray extends Array<string> {
isStringArray(): true {
return true
}
}
console.log(new StringArray('1', '2')) // StringArray [ '1', '2' ]
// StringArrayクラスのメソッドが使える
console.log(new StringArray('1', '2').isStringArray()) // true
しかし、親クラスのconcat
メソッドを叩くとStringArray
ではなく、親クラスのArray<string>
が返ってきてしまう。
error TS2339: Property 'isStringArray' does not exist on type 'string[]'.
41 console.log(strings.concat(strings).isStringArray())
~~~~~~~~~~~~~
これを回避するにはbind
を呼ぶ必要がある
console.log(strings.concat.bind(strings)(strings).isStringArray())
// true
毎回bind
するのが手間であればconcat
メソッドをオーバーライドしておいてもよい
class StringArray extends Array<string> {
isStringArray(): true {
return true
}
concat(that: StringArray): StringArray {
return super.concat.bind(this)(that)
}
}
const strings = new StringArray('1', '2')
console.log(strings)
console.log(strings.concat(strings))
さらに基底クラスを作っておくのもあり
abstract class BaseArray<A> extends Array<A> {
concat<T extends BaseArray<A>>(that: T): T {
return super.concat.bind(this)(that)
}
}
class StringArray extends BaseArray<string> {
isStringArray(): true {
return true
}
}