Wie verwende ich eine externe Nicht-Typoskript-Bibliothek aus Typoskript ohne .d.ts?

100

Ich habe diese in meiner HTML-Datei definiert:

<script type="text/javascript" src="bower_components/tree.js/tree.min.js"></script>
<script type="text/javascript" src="bower_components/q/q.js"></script>
<script type="text/javascript" src="test.js"></script>

Dann in test.js:

 var myTree = Tree.tree({})

Aber Typescript-Fehler sagen: "Name 'Baum' kann nicht gefunden werden"

Ich habe auch versucht, mit der Datei test.js zu kompilieren --module amdund sie import Tree = require("model/tree");oben zu platzieren, aber es tritt erneut ein Fehler auf: Cannot find external module 'model/tree'.Es sollte jedoch eindeutig ein gültiger Import sein, siehe hier, wo er definiert wurde: https://github.com/marmelab/tree .js / blob / master / src / main.js

Ich möchte nicht .d.ts-Dateien für jede einzelne externe Javascript-Datei schreiben, die ich verwenden möchte. Ist das ernsthaft das, was Typescript von mir verlangt?

Blub
quelle
1
Sie müssen keine .d.ts-Dateien schreiben. Siehe stackoverflow.com/questions/27273489/... für ein Beispiel
xmojmr
Interessant, dafür müsste ich allerdings noch Objekte deklarieren. Ich hatte den Eindruck, dass Typescript vollständig mit Javascript kompatibel ist. Ich denke, es ist aus Sicht von Typescript sinnvoll, es muss irgendwie den Code lesen und wenn es keine guten Referenzen hätte, wären es Fehler.
Blub

Antworten:

124

Ich möchte nicht .d.ts-Dateien für jede einzelne externe Javascript-Datei schreiben, die ich verwenden möchte. Ist das ernsthaft das, was Typescript von mir verlangt?

Nein. Die einfachste / schnellste Lösung besteht darin, einfach zu sagen, dass es da draußen eine Variable Treegibt. Dies ist so einfach wie:

declare var Tree:any; // Magic
var myTree = Tree.tree({})

TypeSafety ist eine gleitende Skala in TypeScript. In diesem Fall teilen Sie dem Compiler nur mit, dass es etwas gibt, Treedas Sie verwalten werden, und kümmern sich nicht um viel Typensicherheit, außer der Tatsache, dass es vorhanden ist .

Mehr

IMHO: Die Zeile declare var Tree:any;ist viel einfacher syntaktisch als bei anderen JS-Tools, die Sie schreiben müssten, um die Verwendung von Variablen zu deklarieren, die in Ihrem Code nicht vorhanden sind.

Aktualisieren

interface ITree {
    .. further methods and properties...
}

interface ITreeFactory {
    tree(input: { [key: string]: any }): Itree
};

declare var Tree: ITreeFactory; // magic...
Basarat
quelle
Es hat sich für mich beschwert, als ich diese Methode angewendet habe. Ich musste die Methode anwenden, die Anton unten darlegt. Ihr Kilometerstand kann jedoch variieren! Danke für die Antwort basarat.
Tiz
Sie können den Typ auch als Schnittstelle angeben, anstatt eine, die eine bessere Intelligenz bietet.
Akash Kava
24

Sie können 'require' selbst definieren und die undokumentierte amd-Abhängigkeitsfunktion von TypeScript verwenden:

/// <amd-dependency path="model/tree" />
declare var require:(moduleId:string) => any;
var Tree = require("model/tree");

Die Direktive 'amd-dependency' weist den Compiler an, Ihr Modul einzuschließen, um Argumente im generierten Code zu "definieren": Ein Beispiel finden Sie hier .

Sie können auch einen sehr guten Artikel lesen, in dem erklärt wird, wie TypeScript mit RequireJS verwendet wird.

Beachten Sie jedoch, dass Sie ohne das Schreiben der richtigen TypeScript-Definitionen für Ihren vorhandenen Code keine Typinformationen erhalten und daher keine Typensicherheitsprüfungen, keine erweiterte Code-Vervollständigung in Tools usw. erhalten. Ihr 'Baum' ist also tatsächlich vom Typ 'any' und tatsächlich ein dynamisches JS-Teil in einem anderen TS-Code.

Anton
quelle
Bei der Verwendung von Webpack ist dies keine gute Idee. Für Webpack muss dieses Modul beim Transpilieren vorhanden sein ...
Akash Kava