2017-05-02 80 views
1

我最近開始使用Typescript,並且遇到需要在我的應用程序中需要npm模塊的需求。由於所述npm模塊沒有它自己的類型定義,我還決定分叉並添加我自己的。它能有多難?無法將模塊聲明添加到導出功能的節點包中

Here是故宮模塊我在我的項目安裝:

/** 
* 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 + '' 
} 

夠簡單,它只是出口單一的功能。現在讓我們看看如何得到它打字稿工作...

嘗試#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://stackoverflow.com/q/41891795/3012550,http://stackoverflow.com/q/24029462/3012550等有什麼問題? – alexanderbird

+0

直到幾分鐘前,我將'compilerOptions.module'切換到'commonjs',這對我無效。我覺得有必要改變我的項目的設置,因爲一個包,但如果這是它必須做的唯一方法,我猜... – Loupax

回答

2

我相信你正在尋找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