【问题标题】:Typescript internal modules - unable to reference exported class within same moduleTypescript 内部模块 - 无法在同一模块中引用导出的类
【发布时间】:2015-05-20 14:23:20
【问题描述】:

嗨!

首先,抱歉,如果之前有人问过这个问题,我尝试了一些谷歌搜索,但找不到任何东西(至少没有我认为是同样的问题)。我是 Typescript 的新手,所以还是要掌握!

我正在制作一个小游戏作为一个项目来复习我的 JavaScript,并决定使用 Typescript,因为它似乎非常适合模块化我的应用程序。它都在节点服务器上运行 - 如果需要,我可以提供版本号!

我有两个文件,player.tsscene.ts,它们都属于同一个模块(因为它们是我程序的一部分,但我想要为了模块化而将它们分开):

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

这两个文件都在同一个文件夹中,当我尝试编译它们时:

tsc player.ts scene.ts --module commonjs

我得到错误:

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

如果我删除对 Three 的引用和导入,则编译正常,但显然我需要在类中使用 Three。 (播放器类中也需要三个,以后可能会更多)看起来它实际上编译了JS文件,即使有错误,我不知道为什么。

  • 我不明白这是如何工作的?

  • 使用外部模块和内部模块是否有一些限制? 模块?

  • 有没有办法导入我的应用程序的所有外部类 需要(三,socket.io等)在它自己的TS文件中进行这项工作, 如果这是一个解决方案?

提前致谢!

回答:

解决方案是,使用 commonJS,您需要显式导出和导入,使用模块并没有真正意义(感谢 @ssube 和 @BGR 的解决方案)。

工作代码:

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;

【问题讨论】:

    标签: javascript compilation compiler-errors typescript tsc


    【解决方案1】:

    如果你想使用 commonjs(我认为你应该),你需要显式地导出和导入 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
    
    • 在使用 commonJS 时使用包装器 modules(如 TheGame)实际上没有意义(事物是孤立的)

    • 您不需要引用 .ts 文件

    【讨论】:

    • 太棒了!这行得通,但是我不得不将 require('./Player') 更改为 require('./player') - 我猜这只是引用 .ts 文件的名称(没有 .ts)?跨度>
    • 是的:它是.ts文件的名称,没有ts扩展名
    • 也只是作为一个注释,播放器:播放器;应该是什么,我想我在调试中留下了任何内容
    【解决方案2】:

    由于您已将它们定义为模块,因此 PlayerTheGame 不可见,即使它们位于同一文件中。这就是模块的目的和力量。

    您需要在scene.ts 内从player.tsimport Player 以使其在该范围内可见。根据您的输出,这可能会转化为 AMD 或 CommonJS 要求。

    引用文件使编译器知道定义并允许验证,但实际上并没有将这些符号拉入当前范围并使它们可用。

    我建议将 Player 设置为其文件的默认导出,以简化您的导入:

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

    【讨论】:

    • 那么我是否正确地说,即使它们在同一个模块名称中,它们也不会看到彼此,因为它们在物理上不同的模块块中?我想正如@BGR 在另一个答案中提到的那样,无论如何在 commonJS 中使用模块是没有意义的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 2020-06-06
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多