Comment utiliser une bibliothèque externe non-dactylographiée à partir de typescript sans .d.ts?

100

J'ai défini ceux-ci dans mon fichier .html:

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

Puis dans test.js:

 var myTree = Tree.tree({})

Mais les erreurs Typescript en disant: "Impossible de trouver le nom 'Tree'"

J'ai aussi essayé de compiler avec --module amdet de placer import Tree = require("model/tree");en haut du fichier test.js, mais il y a encore des erreurs: Cannot find external module 'model/tree'.cependant il devrait clairement s'agir d'une importation valide, voir ici où il a été défini: https://github.com/marmelab/tree .js / blob / master / src / main.js

Je ne pas envie d'écrire des fichiers .d.ts pour chaque fichier javascript externe simple que je veux utiliser, est que sérieusement ce que Tapuscrit veut faire?

Blub
la source
1
Vous n'êtes pas obligé d' écrire des fichiers .d.ts. Voir stackoverflow.com/questions/27273489/… pour un exemple
xmojmr
intéressant, cela me demanderait quand même de déclarer des objets. J'avais l'impression que Typescript était complètement compatible avec javascript. Je suppose que cela a du sens du point de vue Typescript, il doit en quelque sorte lire le code et s'il n'avait pas de références bien, ce serait des erreurs.
Blub du

Réponses:

124

Je ne veux pas écrire de fichiers .d.ts pour chaque fichier javascript externe que je souhaite utiliser, est-ce vraiment ce que Typescript veut que je fasse?

Non. La solution la plus simple / la plus rapide est simplement de lui dire qu'il existe une variable Tree. C'est aussi simple que:

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

TypeSafety est une échelle mobile dans TypeScript. Dans ce cas, vous dites seulement au compilateur qu'il y a quelque chose appelé Treeque vous allez gérer et que vous ne vous souciez pas de beaucoup de sécurité de type au-delà du fait qu'il est là .

Plus

IMHO: La ligne declare var Tree:any;est une syntaxe beaucoup plus simple que les autres outils de vérification JS vous obligeraient à écrire pour déclarer votre utilisation de variables qui ne sont pas présentes dans votre code.

Mettre à jour

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

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

declare var Tree: ITreeFactory; // magic...
basarat
la source
Il se plaignait pour moi quand j'ai utilisé cette méthode. J'ai dû utiliser la méthode qu'Anton expose ci-dessous. Votre kilométrage peut cependant varier! Merci pour la réponse basarat.
Tiz
vous pouvez également spécifier le type comme interface au lieu de tout autre qui fournira une meilleure intelligence.
Akash Kava
24

Vous pouvez définir vous-même `` exiger '' et utiliser la fonction de dépendance amd non documentée de TypeScript:

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

La directive 'amd-dependency' dira au compilateur d'inclure votre module pour "définir" les arguments dans le code généré: voir un exemple ici .

Vous pouvez également consulter un très bon article qui explique comment utiliser TypeScript avec RequireJS.

Mais notez que sans écrire les définitions TypeScript appropriées pour votre code existant, vous ne recevrez aucune information de type, et vous n'obtiendrez donc pas de vérifications de sécurité de type, de complétion de code avancée dans les outils, etc. Ainsi, votre 'Tree' sera en fait de type 'any', et sera en fait un élément JS dynamique à l'intérieur d'un autre code TS.

Anton
la source
Ce n'est pas une bonne idée lors de l'utilisation de webpack, webpack nécessitera que ce module soit présent lors du transpiling ...
Akash Kava