Utilisation des tableaux typés en TypeScript
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];
}
Il semble qu'un tableau de type Thing ne soit pas correctement traduit en le type de tableau JavaScript correspondant. Voici un extrait du JavaScript généré :
function Person(name) {
this._name = name;
this._possessions = new Entities.Thing[100]();
}
Exécution de code contenant un objet Personne, lancer 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 en any[] et que j'initialise _possession avec new Array(), aucune exception n'est levée. Ai-je oublié quelque chose ?
Réponse #1
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 de choses, vous pouvez simplement utiliser l'expression littérale de tableau :
this._possessions = [];
Du constructeur de tableau si vous voulez définir la longueur :
this._possessions = new Array(100);
J'ai créé un bref exemple fonctionnel que vous pouvez essayer dans le bac à sable.
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();
}
}
}
Réponse #2
Il existe deux options de syntaxe disponibles lors de la déclaration d’un tableau en TypeScript. La documentation TypeScript utilise Array<T>, cependant ts-lint préfère T[].
En utilisant le Array<Thing>, on utilise les génériques en TypeScript. C'est similaire à demander un List<T> dans le code C#.
// 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
ou
// 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
}
Réponse #3
La traduction est correcte, la saisie de l'expression ne l'est pas. TypeScript tape incorrectement l'expression new Thing[100] comme un tableau. Il devrait y avoir une erreur lorsqu'on indexe Thing, une fonction constructeur, en utilisant l'opérateur d'indice. En C#, cela allouerait un tableau de 100 éléments. En JavaScript, cela appelle la valeur à l'index 100 de Thing comme si c'était un constructeur. Comme cette valeur est undefined, cela génère l'erreur que vous avez mentionnée. En JavaScript et TypeScript, vous voulez plutôt new Array(100).
Vous devriez signaler cela comme un bogue sur CodePlex.
