Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you produce a .d.ts "typings" definition file from an existing JavaScript library?

Tags:

typescript

tsc

People also ask

What is D TS file TypeScript?

The "d. ts" file is used to provide typescript type information about an API that's written in JavaScript. The idea is that you're using something like jQuery or underscore, an existing javascript library. You want to consume those from your typescript code.

What is TypeScript Typings?

What are typings? In short, TypeScript adds static typing to JavaScript. Since JavaScript alone does not define such type definitions, they must be written and included in the TypeScript compilation process through additional mechanisms.


There are a few options available for you depending on the library in question, how it's written, and what level of accuracy you're looking for. Let's review the options, in roughly descending order of desirability.

Maybe It Exists Already

Always check DefinitelyTyped (https://github.com/DefinitelyTyped/DefinitelyTyped) first. This is a community repo full of literally thousands of .d.ts files and it's very likely the thing you're using is already there. You should also check TypeSearch (https://microsoft.github.io/TypeSearch/) which is a search engine for NPM-published .d.ts files; this will have slightly more definitions than DefinitelyTyped. A few modules are also shipping their own definitions as part of their NPM distribution, so also see if that's the case before trying to write your own.

Maybe You Don't Need One

TypeScript now supports the --allowJs flag and will make more JS-based inferences in .js files. You can try including the .js file in your compilation along with the --allowJs setting to see if this gives you good enough type information. TypeScript will recognize things like ES5-style classes and JSDoc comments in these files, but may get tripped up if the library initializes itself in a weird way.

Get Started With --allowJs

If --allowJs gave you decent results and you want to write a better definition file yourself, you can combine --allowJs with --declaration to see TypeScript's "best guess" at the types of the library. This will give you a decent starting point, and may be as good as a hand-authored file if the JSDoc comments are well-written and the compiler was able to find them.

Get Started with dts-gen

If --allowJs didn't work, you might want to use dts-gen (https://github.com/Microsoft/dts-gen) to get a starting point. This tool uses the runtime shape of the object to accurately enumerate all available properties. On the plus side this tends to be very accurate, but the tool does not yet support scraping the JSDoc comments to populate additional types. You run this like so:

npm install -g dts-gen
dts-gen -m <your-module>

This will generate your-module.d.ts in the current folder.

Hit the Snooze Button

If you just want to do it all later and go without types for a while, in TypeScript 2.0 you can now write

declare module "foo";

which will let you import the "foo" module with type any. If you have a global you want to deal with later, just write

declare const foo: any;

which will give you a foo variable.


You can either use tsc --declaration fileName.ts like Ryan describes, or you can specify declaration: true under compilerOptionsin your tsconfig.json assuming you've already had a tsconfig.json under your project.


The best way to deal with this (if a declaration file is not available on DefinitelyTyped) is to write declarations only for the things you use rather than the entire library. This reduces the work a lot - and additionally the compiler is there to help out by complaining about missing methods.


As Ryan says, the tsc compiler has a switch --declaration which generates a .d.ts file from a .ts file. Also note that (barring bugs) TypeScript is supposed to be able to compile Javascript, so you can pass existing javascript code to the tsc compiler.


When creating your own library, you can can create *.d.ts files by using the tsc (TypeScript Compiler) command like so: (assuming you're building your library to the dist/lib folder)

tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
  • -d (--declaration): generates the *.d.ts files
  • --declarationDir dist/lib: Output directory for generated declaration files.
  • --declarationMap: Generates a sourcemap for each corresponding ‘.d.ts’ file.
  • --emitDeclarationOnly: Only emit ‘.d.ts’ declaration files. (no compiled JS)

(see the docs for all command line compiler options)

Or for instance in your package.json:

"scripts": {
    "build:types": "tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly",
}

and then run: yarn build:types (or npm run build:types)


as described in http://channel9.msdn.com/posts/Anders-Hejlsberg-Steve-Lucco-and-Luke-Hoban-Inside-TypeScript at 00:33:52 they had built a tool to convert WebIDL and WinRT metadata into TypeScript d.ts