2017-05-02 5 views
1

J'ai commencé à utiliser Typescript récemment et j'ai trouvé nécessaire d'avoir besoin d'un module npm dans mon application. Puisque ce module npm n'a pas de définition de type propre, j'ai également décidé de le fourrer et d'ajouter le mien. À quel point cela peut-il être dur?Impossible d'ajouter des déclarations de module au package de noeud qui exporte la fonction

Here est le module NPM Je l'ai installé sur mon projet:

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

assez simple, il exporte une seule fonction. Maintenant, nous allons voir comment obtenir le travail dactylographié avec elle ...

Tentative n ° 1:

Définition

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} 
} 

code source

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

Code généré

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

Celui-ci génère du code qui fonctionne, mais en même temps donne une erreur. Aussi pas de saisie semi-automatique de mon IDE.

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

atempt # 2

Définition

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} 
} 

Source

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

Generated

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

Ici, je préfère la syntaxe que j'utilise à l'intérieur de mon manuscrit et le compilateur semble l'aimer aussi. Les erreurs du compilateur Zero et également les indications de type fonctionnent sur IDEA. Dommage que le code généré me donne une erreur TypeError: zero_fill_1.default is not a function lorsqu'il est exécuté ...

Tentative # 3

Définition

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}; 
} 

Source

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

Generated

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

exactement la même qu'avant ... Le compilateur et IDE comme cela, mais le moteur d'exécution ne

Je pourrais continuer, mais je crois que vous avez l'idée.Est-il possible de rendre ce module npm utilisable à l'intérieur de la machine à écrire sans apporter de changements à son code? Qu'est-ce que je fais de mal et comment puis-je importer cette fonction correctement?

+1

Attendez une seconde - On dirait qu'il ya une poignée de doublons à ce (j'ai remarqué après avoir répondu) . Quel est le problème avec http://stackoverflow.com/q/41891795/3012550, http://stackoverflow.com/q/24029462/3012550, etc.? – alexanderbird

+0

Cela ne fonctionnait pas pour moi jusqu'à il y a quelques minutes où je passais mon 'compilerOptions.module' à' commonjs'. Je trouve un peu intrusif d'avoir à changer les paramètres de mon projet à cause d'un seul paquet mais si c'est la seule façon dont il devra le faire je suppose ... – Loupax

Répondre

2

Je crois que vous cherchez this documentation

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

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

importer ensuite comme:

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

Apparemment, cela fonctionne aussi avec plusieurs définitions de fonctions (surcharge de fonction) – Loupax