Node.js 如何正确使用带有NodeJS目标的TypeScript中的模块和接口?

Node.js 如何正确使用带有NodeJS目标的TypeScript中的模块和接口?,node.js,module,typescript,Node.js,Module,Typescript,我和我的团队对TypeScript和NodeJS都是新手,我们在启动这个项目时遇到了一些严重的问题。它是一个模块化的游戏资产管道,用TypeScript编写,用于NodeJS(我没有参与这里的决策,讨论仍在进行中,但我们仍然需要一个原型) 我们已经对体系结构有了一个很好的想法,但是让原型运行起来有点困难,因为我似乎无法将我的头脑集中在模块如何与接口和外部依赖项相结合的问题上。我们的一些组件还需要使用NodeJS或其他库模块(例如,用于读取/写入文件的NodeJS.fs),我们希望能够使用///r

我和我的团队对TypeScript和NodeJS都是新手,我们在启动这个项目时遇到了一些严重的问题。它是一个模块化的游戏资产管道,用TypeScript编写,用于NodeJS(我没有参与这里的决策,讨论仍在进行中,但我们仍然需要一个原型)

我们已经对体系结构有了一个很好的想法,但是让原型运行起来有点困难,因为我似乎无法将我的头脑集中在模块如何与接口和外部依赖项相结合的问题上。我们的一些组件还需要使用NodeJS或其他库模块(例如,用于读取/写入文件的NodeJS.fs),我们希望能够使用
///reference
添加适当的d.ts文件,以在开发时保持类型安全

假设项目结构的一个例子是:

/pipeline
    /log
        - ILog.d.ts
        - StdOutLog.ts
        - FileLog.ts
        - ...
    /reader
        - IReader.d.ts
        - TextReader.ts
        - ...
    /parser
        - IParser.d.ts
        - XmlParser.ts
        - JsonParser.ts
        - ...
    /task
        - ITask.d.ts
        - JsTask.ts
        - CliTask.ts
        - ...
    /...
我们希望使用它的方式是,我们为我们的接口提供默认实现(包括基本功能,例如运行控制台命令、登录到文件或流、读取JSON和XML配置等),以及接口本身,以便其他团队可以创建自己的扩展(例如,
classgittask扩展CliTask
以封装存储库操作,或者
classjpgreader实现IReader

在呼叫端,在不同的project/runner应用程序中,它的工作原理如下:

import pipeline = require('pipeline');

//...

var log = new pipeline.log.FileLog();
log.info("filelog started");

var parser = new pipeline.parser.XmlParser();
parser.parse(somexmldata);
log.info("parsing XML");

// ...
我很可能只是做错了(tm),但我觉得用TypeScript做我们想做的事情并不容易,特别是考虑到例如日志组件的定义可以很容易地有几个接口和枚举(factory、logger、logitem、logtarget、loglevel).据我所知,NodeJS模块需要是一个单独的JS文件,但即使使用一个
导入
,也会将您的模块变成一个外部模块,而这些模块将不再编译成单个文件,因此对我来说,这似乎是一个相当大的障碍

有没有一种方法可以实现针对NodeJ的TypeScript的结构和预期用途?如果有,文件需要是什么样子(特别是关于模块层次结构和组件FQN,例如pipeline.log.X、pipeline.task.Y等;我如何正确使用
模块
导出
)?如果没有,实现我们目标的合适替代方案是什么


[Update]我已经根据basarat的建议重构了我的原型,它看起来已经比以前好多了。但是,我在使用一个类和另一个类时遇到了编译错误:

error TS2095: Could not find symbol 'LogItem'.
LogItem
是在
/log
中定义的一个类,它由同一文件夹中的
StdOutLog.ts
使用。IntelliJ为它提供了多个定义(显然,一个是
LogItem
类本身,另一个是在导出它的
/log
索引文件中)。我已尝试使用模块表示法
log.LogItem
,但不起作用。将所有默认实现文件添加到全局声明文件也不起作用。[/Update]

[Update2]下面是一些关于错误发生位置的更多代码。我在IntelliJ中没有任何错误/标记,只有在运行grunt ts任务时

//src/log/LogItem.ts:

///
类LogItem实现iLogicem{
// ...
构造函数(级别:LogLevel,消息:string){
// ...
}
公共静态创建(级别:LogLevel,消息:string):ILogItem{
返回新的登录项(级别、消息);
}
// ...
}
导出=登录项;
//src/log/log.ts:

///
类日志实现ILog{
// ...
私有getLogItem(级别:LogLevel,消息:string):ILogItem{

return LogItem.create(级别、消息);//在一个全局
globals.d.ts
文件中引用您所有的
.d.ts
文件,该文件具有
///看起来很棒!我已经根据您的建议重构了原型,我想我很接近了,但是我得到了一个无法解决的编译错误。我将编辑我的问题以添加更多信息。您能分享更多关于错误的代码吗或者你在更新中看到了一些代码示例更新了我的问题。我没有看到
export
关键字的任何用法。这可能有助于理解内部和外部类型脚本模块:@basarat:export
的省略是一个愚蠢的复制/粘贴错误,因为我不得不匆忙离开办公室。对此很抱歉。:(我将更新代码示例。我知道这是一个非常老的问题,但对于稍后遇到它的任何其他人(就像我上周所做的那样),您可能会发现这个typescript样板项目很有帮助:
///<reference path='../pipeline.d.ts'/>
class LogItem implements ILogItem {
    // ...

    constructor(level:LogLevel, message:string) {
        // ...
    }

    public static create(level:LogLevel, message:string):ILogItem {
        return new LogItem(level, message);
    }

    // ...
}

export = LogItem;
///<reference path='../pipeline.d.ts'/>
class Log implements ILog {
    // ...

    private getLogItem(level:LogLevel, message:string):ILogItem {
        return LogItem.create(level, message); // <-- that's where I get the "symbol not found" error
    }

    // ...
}

export = Log;
///<reference path="../typings/node/node.d.ts" />

//grunt-start
/// <reference path="pipeline.ts" />
/// <reference path="log/Log.ts" />
/// <reference path="log/LogFactory.ts" />
/// <reference path="log/LogItem.ts" />
/// <reference path="log/StdLogEmitter.ts" />
/// <reference path="log/log.d.ts" />
/// <reference path="log/log.ts" />
/// <reference path="parser/JsonParser.ts" />
/// <reference path="parser/parser.d.ts" />
/// <reference path="parser/parser.ts" />
//grunt-end
/pipeline
    /globals.d.ts
    /log
        - ILog.d.ts
        - StdOutLog.ts
        - FileLog.ts
        - ...
    /reader
        - IReader.d.ts
        - TextReader.ts
        - ...
    /parser
        - IParser.d.ts
        - XmlParser.ts
        - JsonParser.ts
        - ...
    /task
        - ITask.d.ts
        - JsTask.ts
        - CliTask.ts
        - ...
    /...
/// <reference path='../globals.d.ts'/>
class XMLParser implements IParser{
}
export = XMLParser;
export import XmlParser = require('./xmlParser'); 
// so on 
export import parser = require('./parser/index');
import pipeline = require('./pipeline/index');


var parser = new pipeline.parser.XmlParser();
parser.parse(somexmldata);
log.info("parsing XML");