Utilisation des tableaux typés TypeScript

96

J'ai une définition de classe TypeScript qui commence comme ceci;

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

On dirait qu'un tableau de type Thing n'est pas traduit correctement en type de tableau Javascript correspondant. Voici un extrait du code JavaScript généré:

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

Exécution de code contenant un objet Person, lève une exception lors de la tentative d'initialisation du champ _possession:

L'erreur est «0x800a138f - Erreur d'exécution Microsoft JScript: impossible d'obtenir la valeur de la propriété« 100 »: l'objet est nul ou non défini».

Si je change le type de _possession any[] et initialise _possession avec une new Array()exception, il n'est pas lancé. Ai-je oublié quelque chose?

Klaus Nji
la source

Réponses:

120

Vous avez une erreur dans votre syntaxe ici:

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

Cela ne crée pas un "tableau de choses". Pour créer un tableau d'objets, vous pouvez simplement utiliser l'expression littérale de tableau:

this._possessions = [];

Du constructeur de tableau si vous souhaitez définir la longueur:

this._possessions = new Array(100);

J'ai créé un bref exemple de travail que vous pouvez essayer dans la cour de récréation .

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
la source
2
il ne fixe pas la longueur, mais devrait plutôt préallouer le tableau
Sebastian
pourquoi ne pouvez-vous pas faire private _possessions: Thing[] : []; dans la définition de classe?
SuperUberDuper
54

Vous pouvez essayer l'un ou l'autre. Ils ne me donnent pas d'erreurs.

C'est également la méthode suggérée par le typographie pour la déclaration de tableau .

En utilisant le, Array<Thing>il utilise les génériques en tapuscrit. Cela revient à demander un List<T>code en 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[] = [];

ou

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

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}
Kieran
la source
3
Pour préallouer la taille, utilisez new Array<Thing>(100).
Doug Domeny
1
vous pouvez également utiliser ... <Thing> []
danday74
@ danday74 - J'ai mis à jour pour inclure votre méthode, c'est la valeur par défaut lors de l'utilisation de ts-lint recomended / latest config.
Kieran
9

La traduction est correcte, le typage de l'expression ne l'est pas. TypeScript ne saisit pas correctement l'expression new Thing[100]sous forme de tableau. Cela devrait être une erreur d'indexation Thing, une fonction constructeur, utilisant l'opérateur d'index. En C #, cela allouerait un tableau de 100 éléments. En JavaScript, cela appelle la valeur à l'index 100 de Thingcomme si était un constructeur. Puisque ces valeurs sont, undefinedelles soulèvent l'erreur que vous avez mentionnée. Dans JavaScript et TypeScript, vous voulez à la new Array(100)place.

Vous devriez signaler cela comme un bogue sur CodePlex.

chuckj
la source
1
Je ne veux pas de nouveau tableau (100). Je veux un tableau typé de Thing. Je ne sais pas s'il s'agit d'un bug ou simplement de ma mauvaise interprétation de la spécification du document.
Klaus Nji