TypeScript typed array usage

ArraysTypescript

Arrays Problem Overview


I have a TypeScript class definition that starts like this;

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

Looks like an array of type Thing does not get translated correctly to the corresponding Javascript array type. This is a snippet from the generated JavaScript:

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

Executing code containing a Person object, throw an exception when attempting to initialize the _possession field: > Error is "0x800a138f - Microsoft JScript runtime error: Unable to get value of the property '100': object is null or undefined".

If I change the type of _possession to any[] and initialize _possession with new Array() exception is not thrown. Did I miss something?

Arrays Solutions


Solution 1 - Arrays

You have an error in your syntax here:

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

This doesn't create an "array of things". To create an array of things, you can simply use the array literal expression:

this._possessions = [];

Of the array constructor if you want to set the length:

this._possessions = new Array(100);

I have created a brief working example you can try in the 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();
        }
	}
}

Solution 2 - Arrays

There are two syntax options available when declaring an array in typescript. The typescript docs uses Array<T> however ts-lint prefers T[]

By using the Array<Thing> it is making use of the generics in typescript. It is similar to asking for a List<T> in c# code.

// 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

or

// 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
}

Solution 3 - Arrays

The translation is correct, the typing of the expression isn't. TypeScript is incorrectly typing the expression new Thing[100] as an array. It should be an error to index Thing, a constructor function, using the index operator. In C# this would allocate an array of 100 elements. In JavaScript this calls the value at index 100 of Thing as if was a constructor. Since that values is undefined it raises the error you mentioned. In JavaScript and TypeScript you want new Array(100) instead.

You should report this as a bug on CodePlex.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKlaus NjiView Question on Stackoverflow
Solution 1 - ArraysFentonView Answer on Stackoverflow
Solution 2 - ArraysKieranView Answer on Stackoverflow
Solution 3 - ArrayschuckjView Answer on Stackoverflow