ES6は配列の継承をサポートしていますが、これはTypeScript宣言ファイル(lib.es6.d.ts)には反映されていません。
'filter'や 'slice'のような配列関数はサブクラスの配列を返すので、以下はTypeScriptでコンパイルする必要があります。
class MyArray extends Array {
get size() { return this.length; }
}
var x = new MyArray(10).slice();
x.size;
関数 'reverse'、 'concat'、 'slice'、 'splice'、 'filter'は、タイプ 'this'で返されます。
'map'関数もサブタイプのインスタンスを返しますが、戻り値の型に次のようなジェネリックパラメーターが必要になるため、TypeScriptでどのように表現できるかわかりません。
map<U>(callback: (value: T, index: number, array: this) => U): this<U>
もう1つの問題は、Arrayクラスの静的コンストラクターです。これもコンパイルする必要があります。
var x = MyArray.of(1,2,3);
var y = MyArray.from([1,2,3]);
x.size;
y.size;
@ @speciesシンボルによって追加されたいくつかの追加の複雑さもあります。これを使用して、サブクラスの型シグネチャを変更し、「filter」や「slice」などの関数の戻り値として「this」を使用しないようにすることができます。 したがって、次の例では、サブクラスは、現在宣言ファイルで戻り値の型が定義されている方法で機能します。
class MyArray2 extends Array {
static get [Symbol.species]() { return Array; }
}
ChromeとNode.jsはどちらも、ここに示す配列継承機能をすでに実装しています。
TypeScriptは現在、ポリモーフィックthis
でジェネリックスの再スロットリングを許可していないため、これは困難になります。 #6223を参照してください(この問題は重複と見なされる可能性があります)。
問題は、サブクラスで別の汎用スロットを導入した場合、ポリモーフィックthis
はどのように機能するかということです。 たとえば、配列の配列のみを処理するサブクラスを作成します。この場合、汎用のT
がこのように使用されますT[][]
。 しかし、 Array
のthis
の一般的なスロットはArray
T[]
になりますが、常に機能する方法でそれをどのように表現しますか?
上記の問題には、ジェネリックと組み合わせると多形性が崩壊する例が他にもあります。
'map'の問題は、「Polymorphic'this 'and Generics」で説明した問題と同じですが、他のすべての問題のあるArrayメソッドは、単に' this 'を返すだけで正しく機能する可能性があります。
また、Array.fromメソッドとArray.ofメソッドは別の問題を引き起こします。これは、ArrayConstructorインターフェイスが配列の「this」を参照できる必要があるため、私が知る限り、現在のTypeScript構文で表すことも不可能です。インターフェース。
静的関数は、 Array
をクラスにすることで解決できます。 問題は、 Array
も関数として呼び出すことができるため、呼び出し可能なコンストラクター(https://github.com/Microsoft/TypeScript/issues/183)を記述する方法が必要なことです。 残念ながら、この提案はTC39で行き詰まっていますが、アンビエント宣言用にバージョンを作成することはできます。 これは個別に追跡する必要があると思います。
残りの部分については、 T[]
代わりにthis
を追加できるはずです。 sort
すでにこれを行っていると思います。
最も参考になるコメント
静的関数は、
Array
をクラスにすることで解決できます。 問題は、Array
も関数として呼び出すことができるため、呼び出し可能なコンストラクター(https://github.com/Microsoft/TypeScript/issues/183)を記述する方法が必要なことです。 残念ながら、この提案はTC39で行き詰まっていますが、アンビエント宣言用にバージョンを作成することはできます。 これは個別に追跡する必要があると思います。残りの部分については、
T[]
代わりにthis
を追加できるはずです。sort
すでにこれを行っていると思います。