TypeScript typed array usage

93

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
typescript
asked on Stack Overflow Oct 13, 2012 by Klaus Nji • edited Dec 7, 2015 by CoderPi

3 Answers

116

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();
        }
    }
}
answered on Stack Overflow Oct 13, 2012 by Fenton • edited Mar 27, 2014 by Sorskoot
50

You could try either of these. They are not giving me errors.

It is also the suggested method from typescript for array declaration.

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 -> prefered by ts-lint
private _possessions: Thing[] = [];

or

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

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}
answered on Stack Overflow Mar 6, 2014 by Kieran • edited Jan 24, 2017 by Kieran
8

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.

answered on Stack Overflow Oct 13, 2012 by chuckj

User contributions licensed under CC BY-SA 3.0