d512
d512

Reputation: 34113

Typescript generating javascript that doesn't work

Node is not happy about something in the Javascript that TypeScript is generating and I can't figure out why. Here is the code

Person.ts:

export module Models {
    export class Person {
        id: number;
        firstName: string;
        lastName: string;

        constructor(f: string, l: string) {
            this.firstName = f;
            this.lastName = l;
        }

        public saySomething(): void {
            console.log("my name is %s %s", this.firstName, this.lastName);
        }
    }
}

Database.ts:

import P = module("Person");

export module Database {
    export class DB {
        public findPerson(id: number): P.Models.Person {
            return new P.Models.Person("a", "b");
        }
    }
}

Test.ts:

var D = require("./DB");
var db = new D.Database.DB();
var p = db.findPerson(123);
p.saySomething();

It compiles fine down in Javascript, but there appears to be something wrong with the DB.js file that is being created. When I try to run Test.js in node I get this:

$node Test.js
DB.js:2
(function (Database) {
^
TypeError: object is not a function
    at Object.<anonymous> (DB.js:2:1)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at Object.<anonymous> (Test.js:1:73)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)

It's happening during the import of DB.js. Oddly enough, if I change the findPerson() method to return a string instead of a Person it works fine. It has something to do with creating that Person object.

Here is the Javascript:

(function (Models) {
    var Person = (function () {
        function Person(f, l) {
            this.firstName = f;
            this.lastName = l;
        }
        Person.prototype.saySomething = function () {
            console.log("my name is %s %s", this.firstName, this.lastName);
        };
        return Person;
    })();
    Models.Person = Person;    
})(exports.Models || (exports.Models = {}));


var P = require("./Person")
(function (Database) {
    var DB = (function () {
        function DB() { }
        DB.prototype.findPerson = function (id) {
            return new P.Models.Person("a", "b");
        };
        return DB;
    })();
    Database.DB = DB;    
})(exports.Database || (exports.Database = {}));


var dbx = require("./DB")
var db1 = new dbx.Database.DB();
var p = db1.findPerson(123);
p.saySomething();

Upvotes: 0

Views: 1416

Answers (3)

Mattia Peiretti
Mattia Peiretti

Reputation: 71

For me the problem is that I was trying to import a function for file B, in my main file A

File B:

//other stuff

export function doSomething() {
  //....
}

File A:

import {doSomething} from "./fileB";

doSomething()

BUT, above the function doSomething() in fileB, there was an explicit export like this: File B:


function doSomethingElse() {
    // legacy stuff
}

module.exports = doSomethingElse;

export function doSomething() {
  //....
}

Somehow, PHP Storm didn't signal me...

Upvotes: 0

Fenton
Fenton

Reputation: 250922

The main issue is that you are importing a module named Person, where I think you mean to import the Models module that contains a class named Person.

When you are targeting nodejs, or other CommonJS platforms, you omit the module declarations.

You can also take advantage of auto-properties in the constructor.

So you would have Models.ts:

export class Person {
    id: number;

    constructor (public firstName: string, public lastName: string) {

    }

    public saySomething(): void {
        console.log("my name is %s %s", this.firstName, this.lastName);
    }
}

And Database.ts

import models = module("Models");

export class DB {
    public findPerson(id: number): models.Person {
        return new models.Person("a", "b");
    }
}

Upvotes: 0

Dima Vidmich
Dima Vidmich

Reputation: 1375

without semicolon after var P = require("./Person") javascript thinks than next (...) is call of a function. but you seem have it in Database.ts, so Typescript probably loosing some semicolons in compilation.

Upvotes: 5

Related Questions