无法为requirejs模块创建.d.ts文件

时间:2018-09-08 21:06:14

标签: typescript

我有一个使用requirejs编写的模块,需要在Angular 4中工作。为了理解该过程,我创建了一个简化的requirejs模块,并尝试为其创建一个.d.ts文件。但是,我在编译代码时遇到了麻烦。

我的目录结构如下

.
+--index.html
+--lib
|  +-require
|    +--require.js
|
+--js
|  +-bootstrap.ts
   +-test.js
   +-test
     +-index.d.ts

我的index.html文件看起来像这样

<html>
<body>
    ...
    <script type="text/javascript" src="lib/require/require.js" data-main="js/bootstrap"></script>
</body>
</html>

我的bootstrap.js

import test from 'test';
add(5,6);

我的test.js

define(function(){
    return {
       add: function(x, y){
           console.log(x + y);
       return x+y;
       }
    };
});

我的测试/index.d.ts

export function add(a:number, b:number):number;

当我尝试编译bootstrap.ts时,出现此错误

bootstrap.ts(2,18): error TS2307: Cannot find module 'test'.
bootstrap.ts(3,1): error TS2304: Cannot find name 'add'.

1 个答案:

答案 0 :(得分:0)

JavaScript中有3种常见的模块系统类型:AMD(require.js),Common.js(由Node使用)和ES6 modules(尚不可用,没有标记,在Node.js中,但被TypeScript使用,即使TypeScript可以编译到所有3个模块系统上。

AMD是异步的。.这意味着,当您require进行某些操作时,将在回调中提供这些操作(如果可用)。

示例:

// AMD
require("x", (x) => { /* x is available here */ })

另外2个是同步的

// CommonJS
var x = require("x")
// x is available here, synchronously (no callback)
// ES6 Modules
import x from "x"
// x is available here, synchronously (no callback)

在介绍之后,现在回到您的问题...

首先,您的test.d.ts中存在问题。如果test.js如下所示:

define(function(){
    return {
       add: function(x, y){
           console.log(x + y);
       return x+y;
       }
    };
});

比起您假设的,此模块没有返回函数add。实际上,它返回的是一个包含函数add的对象。因此,此JavaScript文件的声明应类似于:

declare module "test" {
    const math: {
        add: (a:number, b:number) => number
    }
    export default math
}

请注意,在此处为define创建声明时,我完全忽略test函数。为什么?由于TypeScript 始终始终使用ES6模块,因此,在编译时,可以在compilerOptions.module中使用tsconfig.json来指定要使用的模块系统。

现在,当您import test模块时,如果需要,您再次使用ES6模块并将TypeScript编译为AMD。

您的bootstrap文件将是这样的:

import test from "test"
console.log(test.add(3,4))

同样,您的假设是错误的。如果导入模块test,则不能一无所获地调用add。您必须致电test.add

现在,如果您使用amd作为TypeScript模块系统,则已编译 bootstrap文件将如下所示:

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
define(["require", "exports", "test"], function (require, exports, test_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    test_1 = __importDefault(test_1);
    console.log(test_1.default.add(3, 4));
});