Uso de array tipado TypeScript

96

Eu tenho uma definição de classe TypeScript que começa assim;

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 um array do tipo Thing não é traduzido corretamente para o tipo de array Javascript correspondente. Este é um snippet do JavaScript gerado:

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

Ao executar o código que contém um objeto Person, lance uma exceção ao tentar inicializar o campo _possession:

O erro é "0x800a138f - erro de tempo de execução do Microsoft JScript: não é possível obter o valor da propriedade '100': o objeto é nulo ou indefinido".

Se eu alterar o tipo de _possession para any[] e inicializar _possession com new Array()exceção, não será lançada. Perdi alguma coisa?

Klaus Nji
fonte

Respostas:

120

Você tem um erro em sua sintaxe aqui:

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

Isso não cria uma "série de coisas". Para criar uma série de coisas, você pode simplesmente usar a expressão literal da matriz:

this._possessions = [];

Do construtor de matriz, se você quiser definir o comprimento:

this._possessions = new Array(100);

Eu criei um breve exemplo de trabalho que você pode experimentar no playground .

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
fonte
2
ele não fixa o comprimento, mas deve pré-alocar a matriz
Sebastian
por que você não pode fazer private _possessions: Thing[] : []; na definição de classe?
SuperUberDuper
54

Você pode tentar qualquer um destes. Eles não estão me dando erros.

É também o método sugerido a partir do typescript para a declaração do array .

Ao usar o Array<Thing>, está fazendo uso dos genéricos no texto datilografado. É semelhante a pedir um List<T>código em 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
fonte
3
Para pré-alocar o tamanho, use new Array<Thing>(100).
Doug Domeny
1
você também pode usar ... <Coisa> []
danday74 de
@ danday74 - Eu atualizei para incluir seu método, é o padrão ao usar ts-lint recomendado / configuração mais recente.
Kieran
9

A tradução está correta, a digitação da expressão não. TypeScript está digitando incorretamente a expressão new Thing[100]como uma matriz. Deve ser um erro indexar Thing, uma função construtora, usando o operador de índice. Em C #, isso alocaria uma matriz de 100 elementos. Em JavaScript, isso chama o valor no índice 100 de Thingcomo se fosse um construtor. Como esses valores são, undefinedisso gera o erro que você mencionou. Em JavaScript e TypeScript você deseja new Array(100).

Você deve relatar isso como um bug no CodePlex.

chuckj
fonte
1
Eu não quero um novo Array (100). Eu quero um array digitado de Thing. Não sei se isso é um bug ou apenas minha má interpretação das especificações do documento.
Klaus Nji