TypeScript声明第三方模块

65

我该如何声明一个长这样的第三方模块:

在第三方模块中:

module.exports = function foo(){
  // do somthing
}
在我的代码中:
import * as foo from 'foo-module'; // Can not find a declaration module for ...
foo();
2个回答

72

请查看有关使用第三方模块的文档

如何编写声明取决于模块的编写方式和导出内容。

你提供的示例是一个 CommonJS 模块(module.exports = ...),它不是真正的 ES6 模块,因为 ES6 不能将函数作为模块导出(只能导出函数成员或默认函数)。

TypeScript 2.7+ 的更新

通过添加esModuleInterop 编译选项,您不再需要使用下面显示的“命名空间 hack”来处理具有非 ES6 兼容性导出的 CommonJS 模块。

首先,请确保在 tsconfig.json 中启用了 esModuleInterop(现在已默认包含在 tsc—init 中):

{
  "compilerOptions" {
    ...
    "esModuleInterop": true,
    ...
   }
}

在一个 .d.ts 文件中声明你的 foo-example,示例如下:

declare module "foo-module" {
  function foo(): void; 
  export = foo;
}

现在你可以像你想要的那样将它作为命名空间导入:

import * as foo from "foo-module";
foo();

或者作为默认导入:

import foo from "foo-module";
foo();

旧的解决方法

你可以在一个 .d.ts 文件中这样声明你的 foo-example

declare module "foo-module" {
  function foo(): void; 
  namespace foo { } // This is a hack to allow ES6 wildcard imports
  export = foo;
}

然后按照您想要的方式进行导入:

import * as foo from "foo-module";
foo();

或者像这样:

import foo = require("foo-module");
foo();

这份文档提供了关于声明文件的良好资源以及适用于各种声明文件的模板


如果在模块内已经调用了 foo() 并且其结果被导出,那么该如何进行类型定义呢? - Alper

5

我曾经遇到过类似的问题,困扰了好一段时间,尝试将类型定义文件添加到我的项目中。最终,我通过以下步骤成功解决了这个问题。

这是一个模块(只有常量),我们可以称之为some-module - node_modules/some-module/index.js。

'use strict';

exports.__esModule = true;
var APPS = exports.APPS = {
    ona: 'ona',
    tacq: 'tacq',
    inetAcq: 'inetAcq'
};

首先,我需要在 tsconfig.json 文件中添加 baseUrltypeRoots

{
  ...
  "compilerOptions": {
    ...
    "baseUrl": "types",
    "typeRoots": ["types"]
  }
  ...
}

在我的项目根目录下,我创建了一个名为types的文件夹,该文件夹具有与模块types/some-module/index.js相同的文件夹结构,并放置了以下代码:

declare module 'some-module' {
    type Apps =  {
        ona: string;
        tacq: string;
        inetAcq: string;
    };
    let APPS: Apps
}

最后我可以在我的my-file.ts中导入它,并带有类型声明!
import { APPS } from 'some-module';

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