Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How use an external non-typescript library from typescript without .d.ts?

I have defined these in my .html file:

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

Then in test.js:

 var myTree = Tree.tree({}) 

But Typescript errors out saying: "Cannot find name 'Tree'"

I also tried compiling with --module amd and placing import Tree = require("model/tree"); at the top of the test.js file, but it errors out again: Cannot find external module 'model/tree'. however clearly it should be a valid import, see here where it was defined: https://github.com/marmelab/tree.js/blob/master/src/main.js

I do not want to write .d.ts files for every single external javascript file I want to use, is that seriously what Typescript wants me to do?

like image 751
Blub Avatar asked Dec 11 '14 07:12

Blub


People also ask

How do I use external plain JavaScript libraries in TypeScript projects?

First include the library source file before the compiled TypeScript file of your project, using script tag in your HTML file. declare var libGlobal: any; You need to replace libGlobal with your library global object which gives access to the library API. Then just use any library function just like normal.

Can I use TypeScript libraries from JavaScript code?

You can create type definition files for any proprietary JavaScript code. Even if a JavaScript library doesn't have a type definition file, you can still use it in your TypeScript project.


2 Answers

I do not want to write .d.ts files for every single external javascript file I want to use, is that seriously what Typescript wants me to do?

No. The simplest / quickest solution is simply to tell it that there is some variable Tree out there. This is as simple as:

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

TypeSafety is a sliding scale in TypeScript. In this case you are only telling the compiler that there is something called Tree that you will manage and don't care for much typesafety beyond the fact that it is there.

More

IMHO: The line declare var Tree:any; is much simpler syntax than other JS veficiation tools would have you write to declare your usage of variables that are not present in your code.

Update

interface ITree {     .. further methods and properties... }  interface ITreeFactory {     tree(input: { [key: string]: any }): Itree };  declare var Tree: ITreeFactory; // magic... 
like image 189
basarat Avatar answered Sep 26 '22 17:09

basarat


You may define 'require' yourself and use undocumented amd-dependency feature of TypeScript:

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

'amd-dependency' directive will tell the compiler to include your module to "define" arguments in generated code: see a sample here.

You may also check a very good article which explains how to use TypeScript with RequireJS.

But note that without writing proper TypeScript definitions for your existing code you won't be provided with any type information, and so you won't get type safety checks, advanced code completion in tools and so on. So, your 'Tree' will actually be of type 'any', and actually will be a dynamic JS piece inside other TS code.

like image 26
Anton Avatar answered Sep 23 '22 17:09

Anton