无法将模块声明添加到导出功能的节点包中

问题描述:

我最近开始使用Typescript,并且遇到需要在我的应用程序中需要npm模块的需求。由于所述npm模块没有它自己的类型定义,我还决定分叉并添加我自己的。它能有多难?无法将模块声明添加到导出功能的节点包中

Here是故宫模块我在我的项目安装:

/** 
* Given a number, return a zero-filled string. 
* From http://*.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 + '' 
} 

够简单,它只是出口单一的功能。现在让我们看看如何得到它打字稿工作...

尝试#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. 

Atempt#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模块在打字稿内部可用,而无需更改其实际的代码?我做错了什么,如何正确导入这个功能?

+1

等一下 - 看起来像有重复这种极少数的(我回答后发现) 。 http://*.com/q/41891795/3012550,http://*.com/q/24029462/3012550等有什么问题? – alexanderbird

+0

直到几分钟前,我将'compilerOptions.module'切换到'commonjs',这对我无效。我觉得有必要改变我的项目的设置,因为一个包,但如果这是它必须做的唯一方法,我猜... – Loupax

我相信你正在寻找this documentation

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

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

然后导入为:

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

显然这也适用于多个函数定义(函数重载) – Loupax