如何将一个JavaScript AMD模块导入到外部的TypeScript模块中?

9
如何将javascript AMD模块导入到外部TypeScript模块中?
我正在使用由bower管理的AMD模块对客户端TypeScript程序进行模块化。在此过程中,TypeScript模块成为javascript AMD模块,然后我会发布它。现在,我想在TypeScript模块中包含一个javascript AMD模块,并且不想发布原始的TypeScript和javascript AMD。
我无法弄清楚如何编写我的TypeScript代码,以便加载没有相应TypeScript的javascript AMD模块,而且最近的TypeScript版本似乎还不支持此功能。
如果从0.9.7 TypeScript规范第11.2节的示例开始:
文件main.ts:
import log = require("./log"); 
log.message("hello"); 

文件 log.ts:

export function message(s: string) { 
    console.log(s); 
}

我相信我应该能够修改main.ts文件,以便编译器将"log"引用解析为log.js AMD模块。 以下是通过运行tsc --module amd main.ts生成的log.js文件。它是一个正确的AMD模块。

文件log.js:

define(["require", "exports"], function(require, exports) {
    function message(s) {
        console.log(s);
    }
    exports.message = message;
});

为了模拟具有javascript AMD模块的情况,请编译上面的示例,然后删除log.ts文件。如果现在尝试使用相同的命令进行编译,则会出现以下错误:

./main.ts(1,1): error TS2071: Unable to resolve external module '"./log"'.  
./main.ts(1,1): error TS2072: Module cannot be aliased to a non-module type.

我如何修改main.ts以便它可以编译并与log.js AMD模块进行解析? 如果必须,我可以编写log.d.ts文件,但希望有一种方法可以不使用声明文件。 如果我能够学习如何以TypeScript的规范方式实现这一点,那么我就可以继续对我的项目进行完整的模块化。
1个回答

2
如果您只有log.js可用,您可以使用declare告诉typescript关于log的类型信息,例如创建一个log.d.ts文件,那么现在我该如何修改main.ts以便加载和使用这个log.js AMD模块呢?
declare module 'log'{
    export function message(s:string);
}

然后在main.ts文件中使用它:

/// <reference path='log.d.ts'/>    

import log = require('log'); 
log.message("hello"); 

这个代码按照你写的方式可以工作。但是如果我保留原始示例中的名称“./log”,那么它将无法编译。我查阅了语言规范,并找到了第12.1.6节“环境外部模块声明”,其中描述了模块名称必须是顶级(非相对)名称的限制。然而,我找不到为什么会有这样的限制的解释。我只能猜测没有真正需要这样的命名方式?您对这个限制有解释吗?谢谢。 - psnider
Js文件应该来自npm或者你的RequireJS配置。在这两种情况下,名称都不是相对的。 - basarat
我发现使用字符串作为 AMD 模块名称的要求令人困惑,但是我找到了这篇文章描述了它的用法:https://typescript.codeplex.com/wikipage?title=Modules%20in%20TypeScript - psnider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接