【问题标题】:Cannot add module declarations to node package that exports function无法将模块声明添加到导出函数的节点包
【发布时间】:2017-09-30 07:49:38
【问题描述】:

我最近开始使用 Typescript,我发现需要在我的应用程序中添加一个 npm 模块。由于所说的 npm 模块没有它自己的类型定义,我也决定分叉它并添加我自己的。有多难?

Here 是我在项目中安装的 npm 模块:

/**
 * Given a number, return a zero-filled string.
 * From http://stackoverflow.com/questions/1267283/
 * @param  {number} width
 * @param  {number} number
 * @return {string}
 */
module.exports = function zeroFill (width, number, pad) {
  if (number === undefined) {
    return function (number, pad) {
      return zeroFill(width, number, pad)
    }
  }
  if (pad === undefined) pad = '0'
  width -= number.toString().length
  if (width > 0) return new Array(width + (/\./.test(number) ? 2 : 1)).join(pad) + number
  return number + ''
}

很简单,它只导出一个函数。现在让我们看看如何让 typescript 使用它...

尝试 #1:

定义

declare module "zero-fill"{
     export function zeroFill(width:number, num:number, pad?:string|number):string
     export function zeroFill(width:number):{(num:number, pad?:string|number):string}
}

源代码

import * as zeroFill from "zero-fill";
console.log(zeroFill(10, 10));

生成的代码

"use strict";
exports.__esModule = true;
var zeroFill = require("zero-fill");
console.log(zeroFill(10, 10));

这个生成的代码可以工作,但同时会出错。我的 IDE 也没有自动完成功能。

Cannot invoke an expression whose type lacks a call signature. Type 'typeof "zero-fill"' has no compatible call signatures.

尝试 #2

定义

declare module "zero-fill"{
     // Notice the default keywords
     export default function zeroFill(width:number, num:number, pad?:string|number):string
     export default function zeroFill(width:number):{(num:number, pad?:string|number):string}
}

来源

import zeroFill from "zero-fill";
console.log(zeroFill(10, 10));

生成

"use strict";
exports.__esModule = true;
var zero_fill_1 = require("zero-fill");
console.log(zero_fill_1["default"](10, 10));

在这里,我更喜欢我在打字稿中使用的语法,编译器似乎也喜欢它。零编译器错误和类型提示也适用于 IDEA。太糟糕了,生成的代码在运行时给了我一个TypeError: zero_fill_1.default is not a function 错误...

尝试 #3

定义

declare module "zero-fill"{
    function zeroFill(width:number, num:number, pad?:string|number):string
    function zeroFill(width:number):{(num:number, pad?:string|number):string}
    export {zeroFill};
}

来源

import {zeroFill} from "zero-fill";
console.log(zeroFill(10, 10));

生成

"use strict";
exports.__esModule = true;
var zero_fill_1 = require("zero-fill");
console.log(zero_fill_1.zeroFill(10, 10));

和以前一模一样……编译器和IDE是这样的,但运行时不是

我可以继续,但我相信你明白了。是否可以在不更改其实际代码的情况下使这个 npm 模块在打字稿中可用?我做错了什么,如何正确导入此功能?

【问题讨论】:

  • 等一下 - 看起来有一些重复(我在回答后注意到)。 stackoverflow.com/q/41891795/3012550stackoverflow.com/q/24029462/3012550等有什么问题?
  • 直到几分钟前我将compilerOptions.module 切换为commonjs,这对我不起作用。我发现因为一个包而不得不更改我的项目设置有点麻烦,但如果这是唯一的方法,我猜...

标签: typescript type-definition


【解决方案1】:

我相信你在找this documentation

declare module 'zero-fill' {
    function zeroFill() /* etc. */
    export = zeroFill;

    /* for any additional types */
    namespace zeroFill {
        interface FooBar { /* ... */ }
    }
}

然后将其导入为:

import zeroFill = require('zero-fill');

【讨论】:

  • 显然这也适用于多个函数定义(函数重载)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
相关资源
最近更新 更多