Użycie tablicy wpisanej w języku TypeScript

96

Mam definicję klasy TypeScript, która zaczyna się w ten sposób;

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];
        }

Wygląda na to, że tablica typu Thing nie jest poprawnie tłumaczona na odpowiedni typ tablicy JavaScript. Oto fragment wygenerowanego kodu JavaScript:

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

Wykonując kod zawierający obiekt Person, zgłoś wyjątek podczas próby zainicjowania pola _possession:

Błąd to „0x800a138f - błąd środowiska wykonawczego Microsoft JScript: nie można pobrać wartości właściwości„ 100 ”: obiekt jest pusty lub niezdefiniowany”.

Jeśli zmienię typ _possession na any[] i zainicjalizuję _possession z new Array()wyjątkiem nie jest wyrzucany. Przegapiłem coś?

Klaus Nji
źródło

Odpowiedzi:

120

Masz tutaj błąd w swojej składni:

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

To nie tworzy „tablicy rzeczy”. Aby utworzyć tablicę elementów, możesz po prostu użyć wyrażenia dosłownego tablicy:

this._possessions = [];

Z konstruktora tablicy, jeśli chcesz ustawić długość:

this._possessions = new Array(100);

Stworzyłem krótki przykład roboczy, który możesz wypróbować na placu zabaw .

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
źródło
2
nie ustala długości, ale raczej powinien wstępnie przydzielić tablicę
Sebastian
dlaczego nie możesz tego zrobić private _possessions: Thing[] : []; w definicji klasy?
SuperUberDuper
54

Możesz spróbować jednego z nich. Nie popełniają błędów.

Jest to również sugerowana metoda z maszynopisu do deklaracji tablicy .

Używając tego Array<Thing>, korzysta z typów ogólnych w maszynie. Jest to podobne do pytania o List<T>kod w języku C #.

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

lub

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

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}
Kieran
źródło
3
Aby wstępnie przydzielić rozmiar, użyj new Array<Thing>(100).
Doug Domeny
1
możesz też użyć ... <Thing> []
danday74
@ danday74 - Zaktualizowałem, aby uwzględnić twoją metodę, jest ona domyślna podczas korzystania z ts-lint zalecana / najnowsza konfiguracja.
Kieran
9

Tłumaczenie jest poprawne, a wpisanie wyrażenia nie. TypeScript nieprawidłowo wpisuje wyrażenie new Thing[100]jako tablicę. ThingZindeksowanie funkcji konstruktora przy użyciu operatora indeksu powinno być błędem . W C # to przydzieliłoby tablicę 100 elementów. W JavaScript wywołuje to wartość w indeksie 100, Thingjakby była konstruktorem. Ponieważ są to wartości undefined, powoduje to wspomniany błąd. new Array(100)Zamiast tego w JavaScript i TypeScript .

Powinieneś zgłosić to jako błąd w CodePlex.

chuckj
źródło
1
Nie chcę nowego Array (100). Chcę mieć wpisaną tablicę rzeczy. Nie wiem, czy to błąd, czy tylko moja błędna interpretacja specyfikacji dokumentu.
Klaus Nji