ES6 unterstützt die Array-Vererbung, dies spiegelt sich jedoch nicht in der TypeScript-Deklarationsdatei (lib.es6.d.ts) wider.
Array-Funktionen wie 'Filter' und 'Slice' geben ein Array der Unterklasse zurück, daher sollte Folgendes in TypeScript kompiliert werden:
class MyArray extends Array {
get size() { return this.length; }
}
var x = new MyArray(10).slice();
x.size;
Die Funktionen 'reverse', 'concat', 'Slice', 'Splice', 'Filter' sollten mit dem Typ 'this' zurückgegeben werden.
Die 'map'-Funktion gibt auch eine Instanz des Subtyps zurück, aber ich weiß nicht, wie dies in TypeScript dargestellt werden könnte, da ein generischer Parameter im Rückgabetyp erforderlich wäre, etwa:
map<U>(callback: (value: T, index: number, array: this) => U): this<U>
Ein weiteres Problem sind die statischen Konstruktoren der Array-Klasse, die ebenfalls kompiliert werden sollten:
var x = MyArray.of(1,2,3);
var y = MyArray.from([1,2,3]);
x.size;
y.size;
Es gibt auch einige zusätzliche Komplikationen, die durch das @ @ species- Symbol hinzugefügt werden. Typensignatur der Unterklasse so zu ändern, dass 'this' nicht als Rückgabewert für Funktionen wie 'filter' und 'Slice' verwendet wird. Für das folgende Beispiel würde die Unterklasse also so funktionieren, wie die Rückgabetypen derzeit in der Deklarationsdatei definiert sind:
class MyArray2 extends Array {
static get [Symbol.species]() { return Array; }
}
Chrome und Node.js implementieren bereits die hier gezeigten Funktionen zur Array-Vererbung.
Dies wird schwierig, da TypeScript derzeit kein erneutes Slotting von Generika auf polymorphem this
erlaubt. Siehe # 6223 (von dem dieses Problem als Betrug angesehen werden könnte).
Das Problem wird, wenn Sie in einer Unterklasse einen anderen generischen Slot einführen. Wie funktioniert polymorphes this
? Beispielsweise erstellen Sie eine Unterklasse, die sich nur mit Arrays von Arrays befasst, wobei das generische T
auf diese Weise T[][]
. Aber der generische Slot in Array
's this
wäre T[]
. Wie können Sie das so ausdrücken, dass es immer funktioniert?
In der oben genannten Ausgabe gibt es weitere Beispiele dafür, wo polymorph dies in Kombination mit Generika zusammenbricht.
Das Problem mit 'map' ist in der Tat das gleiche wie das in "Polymorphic 'this' und Generics" beschriebene, aber alle anderen problematischen Array-Methoden könnten korrekt funktionieren, wenn einfach 'this' zurückgegeben wird.
Und die Methoden Array.from und Array.of erzeugen ein separates Problem, das meines Wissens mit der aktuellen TypeScript-Syntax nicht dargestellt werden kann, da die ArrayConstructor-Schnittstelle in der Lage sein müsste, auf das 'this' des Arrays zu verweisen Schnittstelle.
Die statischen Funktionen können gelöst werden, indem Array
einer Klasse gemacht wird. Das Problem ist, dass wir eine Möglichkeit haben müssen, einen aufrufbaren Konstruktor (https://github.com/Microsoft/TypeScript/issues/183) zu beschreiben, da Array
auch als Funktion aufgerufen werden kann. Leider ist dieser Vorschlag in TC39 ins Stocken geraten, aber wir können eine Version davon für Umgebungsdeklarationen erstellen. Ich denke, dies sollte separat verfolgt werden.
im Übrigen sollte das Hinzufügen von this
anstelle von T[]
möglich sein. Ich glaube, dass sort
bereits tut.
Hilfreichster Kommentar
Die statischen Funktionen können gelöst werden, indem
Array
einer Klasse gemacht wird. Das Problem ist, dass wir eine Möglichkeit haben müssen, einen aufrufbaren Konstruktor (https://github.com/Microsoft/TypeScript/issues/183) zu beschreiben, daArray
auch als Funktion aufgerufen werden kann. Leider ist dieser Vorschlag in TC39 ins Stocken geraten, aber wir können eine Version davon für Umgebungsdeklarationen erstellen. Ich denke, dies sollte separat verfolgt werden.im Übrigen sollte das Hinzufügen von
this
anstelle vonT[]
möglich sein. Ich glaube, dasssort
bereits tut.