Uso de matrices escritas en TypeScript

96

Tengo una definición de clase de TypeScript que comienza así;

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

Parece que una matriz de tipo Thing no se traduce correctamente al tipo de matriz de Javascript correspondiente. Este es un fragmento del JavaScript generado:

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

Al ejecutar un código que contiene un objeto Person, lanza una excepción al intentar inicializar el campo _possession:

El error es "0x800a138f - Error de tiempo de ejecución de Microsoft JScript: no se puede obtener el valor de la propiedad '100': el objeto es nulo o no está definido".

Si cambio el tipo de _possession any[] ay inicializo _possession con new Array()excepción, no se lanza. ¿Me he perdido algo?

Klaus Nji
fuente

Respuestas:

120

Tiene un error en su sintaxis aquí:

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

Esto no crea una "variedad de cosas". Para crear una matriz de cosas, simplemente puede usar la expresión literal de matriz:

this._possessions = [];

Del constructor de la matriz si desea establecer la longitud:

this._possessions = new Array(100);

He creado un breve ejemplo práctico que puedes probar en el patio de recreo .

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
fuente
2
no fija la longitud, sino que debería preasignar la matriz
Sebastian
¿Por qué no puedes hacerlo private _possessions: Thing[] : []; en la definición de clase?
SuperUberDuper
54

Puedes probar cualquiera de estos. No me están dando errores.

También es el método sugerido de mecanografiado para la declaración de matrices .

Al usarlo Array<Thing>, está haciendo uso de los genéricos en mecanografiado. Es similar a pedir un List<T>código 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[] = [];

o

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

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}
Kieran
fuente
3
Para preasignar el tamaño, use new Array<Thing>(100).
Doug Domeny
1
también puede usar ... <Cosa> []
danday74
@ danday74 - He actualizado para incluir su método, es el predeterminado cuando se usa ts-lint recomended / latest config.
Kieran
9

La traducción es correcta, el tipo de expresión no lo es. TypeScript está escribiendo incorrectamente la expresión new Thing[100]como una matriz. Debería ser un error indexar Thing, una función constructora, usando el operador de índice. En C #, esto asignaría una matriz de 100 elementos. En JavaScript, esto llama al valor en el índice 100 Thingcomo si fuera un constructor. Dado que ese valor es undefined, plantea el error que mencionaste. En JavaScript y TypeScript lo que desea es new Array(100).

Debería informar esto como un error en CodePlex.

chuckj
fuente
1
No quiero una nueva matriz (100). Quiero una matriz escrita de Thing. No sé si esto es un error o simplemente mi mala interpretación de las especificaciones del documento.
Klaus Nji