Verwendung von TypeScript-typisierten Arrays

96

Ich habe eine TypeScript-Klassendefinition, die so beginnt.

module Entities {          

    export class Person {
        private _name: string;
        private _possessions: Thing[];
        private _mostPrecious: Thing;

        constructor (name: string) {
            this._name = name;
            this._possessions = new Thing[100];
        }

Es sieht so aus, als würde ein Array vom Typ Thing nicht korrekt in den entsprechenden Javascript-Array-Typ übersetzt. Dies ist ein Ausschnitt aus dem generierten JavaScript:

function Person(name) {
    this._name = name;
    this._possessions = new Entities.Thing[100]();
}

Wenn Sie Code ausführen, der ein Personenobjekt enthält, lösen Sie eine Ausnahme aus, wenn Sie versuchen, das Feld _possession zu initialisieren:

Fehler ist "0x800a138f - Microsoft JScript-Laufzeitfehler: Wert der Eigenschaft '100' kann nicht abgerufen werden: Objekt ist null oder undefiniert".

Wenn ich den Typ von _possession ändere any[] und _possession mit new Array()Ausnahme initialisiere, wird dies nicht ausgelöst. Habe ich etwas verpasst?

Klaus Nji
quelle

Antworten:

120

Sie haben hier einen Fehler in Ihrer Syntax:

this._possessions = new Thing[100]();

Dies schafft keine "Reihe von Dingen". Um ein Array von Dingen zu erstellen, können Sie einfach den Array-Literalausdruck verwenden:

this._possessions = [];

Vom Array-Konstruktor, wenn Sie die Länge festlegen möchten:

this._possessions = new Array(100);

Ich habe ein kurzes Arbeitsbeispiel erstellt, das Sie auf dem Spielplatz ausprobieren können .

module Entities {  

    class Thing {

    }        

    export class Person {
        private _name: string;
        private _possessions: Thing[];
        private _mostPrecious: Thing;

        constructor (name: string) {
            this._name = name;
            this._possessions = [];
            this._possessions.push(new Thing())
            this._possessions[100] = new Thing();
        }
    }
}
Fenton
quelle
2
es legt nicht die Länge fest, sondern sollte das Array vorab zuordnen
Sebastian
Warum kannst du das nicht private _possessions: Thing[] : []; in der Klassendefinition tun ?
SuperUberDuper
54

Sie können beides ausprobieren. Sie geben mir keine Fehler.

Es ist auch die vorgeschlagene Methode aus Typoskript für die Array-Deklaration .

Durch die Array<Thing>Verwendung von werden die Generika in Typoskript verwendet. Es ist ähnlich wie nach einem List<T>In-C # -Code zu fragen .

// Declare with default value
private _possessions: Array<Thing> = new Array<Thing>();
// or
private _possessions: Array<Thing> = [];
// or -> prefered by ts-lint
private _possessions: Thing[] = [];

oder

// declare
private _possessions: Array<Thing>;
// or -> preferd by ts-lint
private _possessions: Thing[];

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}
Kieran
quelle
3
Verwenden Sie, um die Größe vorab zuzuweisen new Array<Thing>(100).
Doug Domeny
1
Sie können auch ... <Thing> []
danday74
@ danday74 - Ich habe aktualisiert, um Ihre Methode einzuschließen. Dies ist die Standardeinstellung bei Verwendung der empfohlenen / neuesten Konfiguration von ts-lint.
Kieran
9

Die Übersetzung ist korrekt, die Eingabe des Ausdrucks nicht. TypeScript gibt den Ausdruck fälschlicherweise new Thing[100]als Array ein. Es sollte ein Fehler sein Thing, eine Konstruktorfunktion mit dem Indexoperator zu indizieren. In C # würde dies ein Array von 100 Elementen zuweisen. In JavaScript ruft dies den Wert am Index 100 auf, Thingals wäre es ein Konstruktor. Da dieser Wert ist undefined, wird der von Ihnen erwähnte Fehler ausgelöst. In JavaScript und TypeScript möchten Sie new Array(100)stattdessen.

Sie sollten dies als Fehler in CodePlex melden.

chuckj
quelle
1
Ich möchte kein neues Array (100). Ich möchte ein typisiertes Array von Thing. Ich weiß nicht, ob dies ein Fehler ist oder nur meine Fehlinterpretation der Dokumentenspezifikation.
Klaus Nji