简体   繁体   中英

Typescript internal modules - unable to reference exported class within same module

Hi!

First off, sorry if this has been asked before, I tried some Googling but wasn't able to find anything (at least nothing that I recognised as being the same problem). I'm new to Typescript so still getting to grips!

I'm making a little game as a project to brush up on my JavaScript, and decided to use Typescript since it seems like a good fit for modularising my application. It's all running on a node server - I can provide version numbers if required!

I have two files, player.ts and scene.ts , these both belong to the same module (in that they are part of my program, but I want to split them up for the sake of modularity):

player.ts

module TheGame {
    export class Player {
        name: string;
        constructor(name: string) { 
            this.name = name;
        }
    }
}

scene.ts

///<reference path="player.ts"/>
///<reference path="../typings/threejs/three.d.ts"/>
import jquery = require("three");

module TheGame {
    export class Scene {
        player: any;
        constructor() {
            this.player = new Player('test');
        }
        //Use of Three throughout file
    }
}

Both of these files are in the same folder, and when I try to compile them with:

tsc player.ts scene.ts --module commonjs

I get the error:

testscene.ts(10,22): error TS2095: Could not find symbol 'Player'.

If I remove the reference and the import to Three, this compiles fine , but obviously I need to use Three in the class. (Three is also required in the player class, and probably more later) It seems like it actually compiles the JS files even though there's an error, I'm not sure why.

  • What am I not understanding about how this works?

  • Is there some restriction on using external modules and internal modules?

  • Is there a way to import all the external classes my application needs (Three, socket.io, etc.) in it's own TS file to make this work, if that's a solution?

Thanks in advance!

ANSWERED:

The solution was that, using commonJS, you need to explicitly export and import, and using modules doesn't really make sense (thanks to @ssube and @BGR for the solution).

Working code:

player.ts

export class Player {
    name: string;
    constructor(name: string) { 
        this.name = name;
    }
}

export = Player;

scene.ts

///<reference path="../typings/threejs/three.d.ts"/>
import jquery = require("three");
import Player = require("./player");

class Scene {
    player: Player;
    constructor() {
        this.player = new Player('test');
    }
    //Use of Three throughout file
}

export = Scene;

If you want to use commonjs (and I think you should) you need to explicitly export and import try

player.ts

class Player {
    name: string;
    constructor(name: string) { 
        this.name = name;
    }
}

export = Player

scene.ts

///<reference path="../typings/threejs/three.d.ts"/>
import jquery = require("three");  //I guess 'jquery' is a typo
import Player = require('./Player')

class Scene {
    player: any; //any -> Player ?
    constructor() {
        this.player = new Player('test');
    }
    //Use of Three throughout file
}

export = Scene //if this makes sense
  • use of wrapper modules (like TheGame ) do not really make sense when using commonJS (things are isolated)

  • you do not need to reference .ts files

Since you've defined them as modules, Player wouldn't be visible to TheGame even if they were in the same file. That's the purpose and power of modules.

You need to import Player from player.ts within scene.ts to make it visible in that scope. Depending on your output, this may translate into an AMD or CommonJS require.

Referencing the file makes the compile aware of the definition and allows validation, but doesn't actually pull those symbols into the current scope and make them usable.

I would suggest making Player the default export from its file to simplify your imports into:

///<reference path="player.ts"/>
///<reference path="../typings/threejs/three.d.ts"/>
import jquery = require("three");
import Player = require("player");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM