Использование типизированного массива TypeScript

96

У меня есть определение класса TypeScript, которое начинается так;

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

Похоже, что массив типа Thing некорректно переводится в соответствующий тип массива Javascript. Это фрагмент из сгенерированного JavaScript:

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

Выполняя код, содержащий объект Person, генерирует исключение при попытке инициализировать поле _possession:

Ошибка: «0x800a138f - ошибка времени выполнения Microsoft JScript: невозможно получить значение свойства« 100 »: объект имеет значение null или undefined».

Если я изменю тип _possession на any[] и инициализирую _possession, new Array()исключение не будет выбрано . Я что-то пропустил?

Клаус Нджи
источник

Ответы:

120

Здесь есть ошибка в синтаксисе:

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

Это не создает «множество вещей». Чтобы создать массив вещей, вы можете просто использовать буквальное выражение массива:

this._possessions = [];

Из конструктора массива, если вы хотите установить длину:

this._possessions = new Array(100);

Я создал небольшой рабочий пример, который вы можете попробовать на детской площадке .

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();
        }
    }
}
Фентон
источник
2
он не фиксирует длину, а должен предварительно выделить массив
Себастьян
почему вы не можете сделать private _possessions: Thing[] : []; в определении класса?
SuperUberDuper
54

Вы можете попробовать любой из них. Они не дают мне ошибок.

Это также предлагаемый метод из машинописного текста для объявления массива .

Используя это, Array<Thing>он использует универсальные типы в машинописном тексте. Это похоже на запрос List<T>кода в 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[] = [];

или

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

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}
Киран
источник
3
Для предварительного распределения размера используйте new Array<Thing>(100).
Дуг Домени
1
вы также можете использовать ... <Thing> []
danday74
@ danday74 - Я обновил, чтобы включить ваш метод, он используется по умолчанию при использовании ts-lint recomended / latest config.
Киран
9

Перевод правильный, написание выражения - нет. TypeScript неправильно набирает выражение new Thing[100]как массив. ThingИндексирование функции-конструктора с использованием оператора индексации должно вызвать ошибку . В C # это выделит массив из 100 элементов. В JavaScript это вызывает значение с индексом 100, Thingкак если бы это был конструктор. Поскольку это значения, undefinedвозникает упомянутая вами ошибка. new Array(100)Вместо этого в JavaScript и TypeScript .

Вы должны сообщить об этом как об ошибке в CodePlex.

чакдж
источник
1
Мне не нужен новый массив (100). Мне нужен типизированный массив Thing. Я не знаю, является ли это ошибкой или просто неправильным толкованием спецификации документа.
Клаус Нджи,