Typescript inclusions

Jul 16, 2014 at 5:18 PM
Hi there,

I'm not actually sure this is the right please to ask this question, but I hope someone will be kind enough to help me.

I'm seriously considering switching to Node.js from PHP. But I don't really like the prototyping in Javascript so I would favor Typescript over this.

I was just testing the basics and created a new (Typescript) Express project.

I created a directory called tstests, added a file called animals.ts with the following code from the Typescript tutorial:
class Animal {
    name: string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Galloping...");
        super.move(45);
    }
}
Then I added this code at the bottom of my app.ts:
/// <reference path='tstests/animals.ts'/>
var sam = new Snake("Sammy the Python");
sam.move();
Both IntelliSense and building the project work, but when I try to run the project I get a ReferenceError: Snake is not defined.

Can anyone explain to me how I have to solve this?
Coordinator
Jul 16, 2014 at 6:32 PM
<reference> is strictly a TypeScript design-time artifact - the IDE uses it for completions, and TypeScript compiler uses it to look up types, but it doesn't do anything in the generated .js code.

If you want one .js file to use code from another .js file in Node, you need to make the second file a module, and export things that you're going to use. The first file then imports it and uses them. Look at the "Going External" section here for details and syntax.
Jul 17, 2014 at 8:19 AM
Hi,

thanks for your response. I have adjusted my code now to the following:

tstests/animals.ts
module Animals {
    export class Animal {
        name: string;
        constructor(theName: string) { this.name = theName; }
        move(meters: number) {
            console.log(this.name + " moved " + meters + "m.");
        }
    }

    export class Snake extends Animal {
        constructor(name: string) { super(name); }
        move() {
            console.log("Slithering...");
            super.move(5);
        }
    }

    export class Horse extends Animal {
        constructor(name: string) { super(name); }
        move() {
            console.log("Galloping...");
            super.move(45);
        }
    }
}

export = Animals;
app.ts
var animals = require('./tstests/animals');
var sam = new animals.Snake("Sammy");
sam.move();
At this point, my application works, but I do not get code completion on the animals object.
Coordinator
Jul 17, 2014 at 9:12 AM
You do not need the explicit module declaration. If you're using one-file-per-module approach (which you should with node), then the top level of the file is your module, and you simply add export to those members that you wish to export - i.e. on top level:
    export class Animal {
        name: string;
        constructor(theName: string) { this.name = theName; }
        move(meters: number) {
            console.log(this.name + " moved " + meters + "m.");
        }
    }
etc. Also, the importing file must use the import keyword in place of var to do the import:
import animals = require('./tstests/animals');
...
Marked as answer by kristoftorfs on 7/17/2014 at 10:22 AM
Jul 17, 2014 at 6:22 PM
That did the trick, thanks!

I have to say, every article I found on the internet just confused me more as some talked about AMD, others CommonJS, RequireJS, ... And none of them had a really clear example on using multiple files.

And in the end after reading up on TypeScript modules I got even more dazed :-)