Användning av typad array i TypeScript
Jag har en TypeScript-klassdefinition som börjar så här;
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];
}
Det ser ut som en array av typen Thing inte översätts korrekt till den motsvarande Javascript-arraytypen. Detta är ett utdrag från den genererade JavaScript:
function Person(name) {
this._name = name;
this._possessions = new Entities.Thing[100]();
}
Körning av kod som innehåller ett Person-objekt, kasta ett undantag när du försöker initiera _possession-fältet:
Fel är "0x800a138f - Microsoft JScript-körtidsfel: Kan inte hämta värdet av egenskapen '100': objektet är null eller odefinierat".
Om jag ändrar typen på _possession till any[] och initierar _possession med new Array() kastas inget undantag. Missade jag något?
Svar #1
Du har ett fel i din syntax här:
this._possessions = new Thing[100]();
Detta skapar inte en "matris av saker". För att skapa en matris av saker kan du helt enkelt använda matrisliteraluttrycket:
this._possessions = [];
Av array-konstruktorn om du vill ställa in längden:
this._possessions = new Array(100);
Jag har skapat ett kort arbetsprov som du kan prova i lekområdet.
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();
}
}
}
Svar #2
Det finns två syntaxalternativ tillgängliga när man deklarerar en array i TypeScript. TypeScript-dokumentationen använder Array<T> men TS-Lint föredrar T[]
Genom att använda Array<Thing> utnyttjas generics i TypeScript. Det är liknande som att begära en List<T> i C#-kod.
// Declare with default value
private _possessions: Array<Thing> = new Array<Thing>(); // or
private _possessions: Array<Thing> = []; // or
private _possessions: Thing[] = []; // or -> prefered by ts-lint
eller
// declare then assign in the constructor
private _possessions: Array<Thing>; // or
private _possessions: Thing[]; // or -> preferd by ts-lint
constructor(){
this._possessions = new Array<Thing>(); // or
this._possessions = []; // or
}
Svar #3
Översättningen är korrekt, men typningen av uttrycket är det inte. TypeScript typar felaktigt uttrycket new Thing[100] som en array. Det borde vara ett fel att indexera Thing, en konstruktionsfunktion, med indexoperatorn. I C# skulle detta allokera en array med 100 element. I JavaScript anropar detta värdet på index 100 av Thing som om det var en konstruktor. Eftersom det värdet är undefined uppstår det fel du nämnde. I JavaScript och TypeScript vill du istället använda new Array(100).
Du bör rapportera detta som ett fel på CodePlex.
