2016-04-12 3 views
0

Ich habe Datei my-module.ts:Typoskript Anruf Signatur Ausgabe

declare module "my-module" { 
    interface main { 
     (string):string, 
     methodName():any, 
     propertyName:any, 
     objectName:Object 
    } 
    export default main; 
} 

und wenn es aus einer Datei mit test.ts:

import * as MyModule from "my-module"; 
var s = MyModule('test'); 

Ich erhalte Fehler Cannot invoke an expression whose type lacks a call signature.

Warum es geschieht, und wie man es repariert?

UPDATE

Nach Vorschlag von Joe Clay, wenn wir den Code dies zu ändern:

declare module "my-module" { 
    interface main { 
     (string):string, 
     methodName():any, 
     propertyName:any, 
     objectName:Object 
    } 
    var myModule: main; 
    export default myModule; 
} 

Und dann versuchen, es wie folgt zu verwenden:

import myModule from "my-module"; 
var s = myModule('test'); 

Es erzeugt das folgende JavaScript:

var my_module_1 = require("my-module"); 
var s = my_module_1["default"]('test'); 

Welche wirft Fehler my_module_1.default is not a function.

UPDATE

Die folgende Änderung beschlossen, das unmittelbare Problem:

declare module "my-module" { 
    interface main { 
     (string):string, 
     methodName():any, 
     propertyName:any, 
     objectName:Object 
    } 
    var myModule: main; 
    export = myModule; // <= Here's the change 
} 

und deren Verwendung:

import * as myModule from "my-module"; 

Doch diese mich mit einem anderen Problem dargestellt. Ich zeigte ein vereinfachtes Beispiel von my-module, während der echte ein paar Klassen und enum -s exportiert hat. Mit der Änderung wie oben können wir das nicht mehr tun.

Umgebungsklassen und enum es sollen exportiert werden mit export enum Name{} und export class Name, aber diese Syntax nicht zulässig ist, wenn export = myModule verwendet wird, einen Fehler erzeugt: An export assignment cannot be used in a module with other exported elements..

Wie korrigieren Sie diese jetzt? :)

Noch mehr Ärger, ich habe ein anderes Modul, das eine Eigenschaft des Typs my-module hat, für die, wenn ich als properName: MyModule deklariere, bekomme ich Cannot find name 'pgMinify'. Ich verstehe nicht, was das bedeutet.

Antwort

2

a) Wenn Sie einen Standard-Export haben, ist die Importsyntax nur import MyModule from "my-module"; - Sie benötigen nicht die * as.

b) Sie können keine Schnittstelle aufrufen. Sie können etwas anrufen, implementiert es, aber versuchen, MyModule() macht keinen Sinn.

EDIT:

Als Reaktion auf den aktualisierten Code - this is a pretty common issue when you're trying to use TypeScript's ES6 imports with a CommonJS module.Microsoft besteht darauf, möglichst an der Spezifikation festzuhalten, anstatt irgendeine Art von Magie zu verwenden, um module.exports in einen ES6-Standard-Export umzuwandeln - technisch sind sie wahrscheinlich richtig, aber vorausgesetzt, dass Babel (wahrscheinlich der beliebteste JavaScript-Transpiler) Konvertierung ist in Ordnung, ich wünschte wirklich, sie würden es auch zu TypeScript hinzufügen.

Der empfohlene Weg, um dieses ist der Import in die import * as MyModule from "my-module"; Syntax zurückzukehren und Ihre Erklärung ändern wie folgt:

declare module "my-module" { 
    interface main { 
     (string):string, 
     methodName():any, 
     propertyName:any, 
     objectName:Object 
    } 
    var myModule: main; 
    export = myModule; // <= Here's the change 
} 

Hoffentlich, dass Sie geben das Ergebnis für Sie suchen.

EDIT 2:

Es wird ein wenig komplexer, wenn Sie Ihre eigenen Arten in Ihrer Erklärung beginnen soll definieren, anstatt nur Primitive - aber nicht zu viel komplizierter. Ein gutes Beispiel für den Anfang ist the type definitions for body-parser. Ich werde hier nicht die ganze Sache kopieren, wie meine Antwort schon verrückt lange erhalten, aber die Dinge zu beachten sind:

  • Sie ein namespace erklären kann, müssen die als Haupt-Export, und dann Export andere Dinge von innen heraus.
  • Es ist möglich, Deklarationen zu "fusionieren" - in der Datei, die ich verlinkt habe, merke, dass sie bodyParser als eine Funktion definieren und dann einen Namespace mit demselben Namen definieren. Diese werden zusammengeführt, was bedeutet, dass die Exporte innerhalb des Namensraums als Eigenschaften der Funktion angezeigt werden (z. B. sind bodyParser() und bodyParser.json() beide verfügbar).

Grundsätzlich ist der beste Rat, den ich Ihnen geben kann, ist die DefinitelyTyped Repository für Module durchsuchen Sie gut kennen, und sehen, wie ihre Definitionen erstellt wurden - es ist der beste Weg, zu lernen, wie es selbst zu tun.

+0

Das ist eine Ambient-Deklaration für ein vorhandenes Node.js-Modul, das in JavaScript geschrieben wird. Wie sonst sollte es dann erklärt werden? –

+0

@ vitaly-t: Sie müssen etwas exportieren, das Ihre 'main' Schnittstelle implementiert, eher die Schnittstelle selbst, denke ich? Also, etwas wie 'var myModule: main; Export default myModule; '. –

+0

Wenn ich das tue, kompiliert der Code, aber es generiert das: 'var my_module_1 = require (" my-module "); var s = my_module_1 ["default"] ('test'); 'was dann mit' my_module_1.default 'auslöst, ist keine Funktion'. –

Verwandte Themen