{"id":915,"date":"2016-12-14T18:11:33","date_gmt":"2016-12-14T18:11:33","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/typescript\/?p=915"},"modified":"2019-02-20T10:45:57","modified_gmt":"2019-02-20T17:45:57","slug":"writing-dts-files-for-types","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/writing-dts-files-for-types\/","title":{"rendered":"Writing Declaration Files for @types"},"content":{"rendered":"<div style=\"font-size: 16px\">\n<p><a href=\"https:\/\/blogs.msdn.microsoft.com\/typescript\/2016\/06\/15\/the-future-of-declaration-files\/\">A while back<\/a> we talked about how TypeScript 2.0 made it easier to grab declaration files for your favorite library. Declaration files, if you&#8217;re not familiar, are just files that describe the shape of an existing JavaScript codebase to TypeScript. By using declaration files (also called <code>.d.ts<\/code> files), you can avoid misusing libraries and get things like completions in your editor.<\/p>\n<p>As a recap of that previous blog post, if you&#8217;re using an npm package named <code>foo-bar<\/code> and it doesn&#8217;t ship any <code>.d.ts<\/code> files, you can just run<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>npm install -S @types\/foo-bar<\/pre>\n<\/div>\n<p>and things will just work from there.<\/p>\n<p>But you might have asked yourself things like &#8220;where do these &#8216;at-types&#8217; packages come from?&#8221; or &#8220;how do I update the <code>.d.ts<\/code> files I get from it?&#8221;. We&#8217;re going to try to answer those very questions.<\/p>\n<h2>DefinitelyTyped<\/h2>\n<p>The simple answer to where our <code>@types<\/code> packages come from is <a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\">DefinitelyTyped<\/a>. DefinitelyTyped is just a simple repository on GitHub that hosts TypeScript declaration files for all your favorite packages. The project is community-driven, but supported by the TypeScript team as well. That means that anyone can help out or contribute new declarations at any time.<\/p>\n<h2>Authoring New Declarations<\/h2>\n<p>Let&#8217;s say that we want to create declaration files for our favorite library. First, we&#8217;ll need to fork <a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\">DefinitelyTyped<\/a>, clone your fork, and create a new branch.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>git clone https:\/\/github.com\/YOUR_USERNAME_HERE\/DefinitelyTyped\ncd DefinitelyTyped\ngit checkout -b my-favorite-library<\/pre>\n<\/div>\n<p>Next, we can run an <code>npm install<\/code> and create a new package using the <code>new-package<\/code> npm script.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>npm install\nnpm run new-package my-favorite-library<\/pre>\n<\/div>\n<p>For whatever library you use, <code>my-favorite-library<\/code> should be replaced with the <strong>verbatim name<\/strong> that it was published with on npm.\nIf for some reason the package doesn&#8217;t exist in npm, mention this in the pull request you send later on.<\/p>\n<p>The <code>new-package<\/code> script should create a new folder named <code>my-favorite-library<\/code> with the following files:<\/p>\n<ul>\n<li><code>index.d.ts<\/code><\/li>\n<li><code>my-favorite-library-tests.ts<\/code><\/li>\n<li><code>tsconfig.json<\/code><\/li>\n<li><code>tslint.json<\/code><\/li>\n<\/ul>\n<p>Finally we can get started writing our declaration files. First fix up the comments for <code>index.d.ts<\/code> by adding the library&#8217;s MAJOR.MINOR version, the project URL, and your username. Then, start describing your library. Here&#8217;s what <code>my-favorite-library\/index.d.ts<\/code> might look like:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148A14\">\/\/ Type definitions for my-favorite-library x.x<\/span>\n<span style=\"color: #148A14\">\/\/ Project: https:\/\/github.com\/my-favorite-library-author\/my-favorite-library<\/span>\n<span style=\"color: #148A14\">\/\/ Definitions by: Your Name Here &lt;https:\/\/github.com\/YOUR_GITHUB_NAME_HERE&gt;<\/span>\n<span style=\"color: #148A14\">\/\/ Definitions: https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped<\/span>\n\n<span style=\"color: #00f\">export<\/span> <span style=\"color: #00f\">function<\/span> getPerpetualEnergy()<span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">any<\/span>[];\n\n<span style=\"color: #00f\">export<\/span> <span style=\"color: #00f\">function<\/span> endWorldHunger(<span class=\"pl-v\">n<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">boolean<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">void<\/span>;<\/pre>\n<\/div>\n<p>Notice we wrote this as a <em>module<\/em> &#8211; a file that contains explicit imports and exports. We&#8217;re intending to import this library through a module loader of some sort, using Node&#8217;s <code>require()<\/code> function, AMD&#8217;s <code>define<\/code> function, etc.<\/p>\n<p>Now, this library might have been written using <a href=\"https:\/\/github.com\/umdjs\/umd\">the UMD pattern<\/a>, meaning that it could either be imported or used as a global. This is rare in libraries for Node, but common in front-end code where you might use your library by including a <code>&lt;script&gt;<\/code> tag. So in this example, if <code>my-favorite-library<\/code> is accessible as the global <code>MyFavoriteLibrary<\/code>, we can tell TypeScript that with this one-liner:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #00f\">export<\/span> <span style=\"color: #00f\">as<\/span> <span style=\"color: #00f\">namespace<\/span> <span class=\"pl-en\">MyFavoriteLibrary<\/span>;<\/pre>\n<\/div>\n<p>So the body of our declaration file should end up looking like this:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148A14\">\/\/ Our exports:<\/span>\n<span style=\"color: #00f\">export<\/span> <span style=\"color: #00f\">function<\/span> getPerpetualEnergy()<span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">any<\/span>[];\n\n<span style=\"color: #00f\">export<\/span> <span style=\"color: #00f\">function<\/span> endWorldHunger(<span class=\"pl-v\">n<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">boolean<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">void<\/span>;\n\n<span style=\"color: #148A14\">\/\/ Make this available as a global for non-module code.<\/span>\n<span style=\"color: #00f\">export<\/span> <span style=\"color: #00f\">as<\/span> <span style=\"color: #00f\">namespace<\/span> <span class=\"pl-en\">MyFavoriteLibrary<\/span>;<\/pre>\n<\/div>\n<p>Finally, we can add tests for this package in <code>my-favorite-library\/my-favorite-library-tests.ts<\/code>:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #00f\">import<\/span> <span class=\"pl-c1\">*<\/span> <span style=\"color: #00f\">as<\/span> <span class=\"pl-smi\">lib<\/span> <span style=\"color: #00f\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>my-favorite-library<span class=\"pl-pds\">\"<\/span><\/span>;\n\n<span style=\"color: #00f\">const<\/span> energy <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">lib<\/span>.<span class=\"pl-en\">getPerpetualEnergy<\/span>()[<span style=\"color: #09885a\">14<\/span>];\n\n<span class=\"pl-smi\">lib<\/span>.<span class=\"pl-en\">endWorldHunger<\/span>(<span style=\"color: #00f\">true<\/span>);<\/pre>\n<\/div>\n<p>And that&#8217;s it. We can then commit, push our changes to GitHub&#8230;<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>git add .\/my-favorite-library\ngit commit -m <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>Added declarations for 'my-favorite-library'.<span class=\"pl-pds\">\"<\/span><\/span>\ngit push -u origin my-favorite-library<\/pre>\n<\/div>\n<p>&#8230;and send a pull request to the <code>master<\/code> branch on DefinitelyTyped.<\/p>\n<p>Once our change is pulled in by a maintainer, it should be automatically published to npm and available. The published version number will depend on the major\/minor version numbers you specified in the header comments of <code>index.d.ts<\/code>.<\/p>\n<h2>Sending Fixes<\/h2>\n<p>Sometimes we might find ourselves wanting to update a declaration file as well. For instance, let&#8217;s say we want to fix up <code>getPerpetualEnergy<\/code> to return an array of <code>boolean<\/code>s.<\/p>\n<p>In that case, the process is pretty similar. We can simply fork &amp; clone DefinitelyTyped as described above, check out the <code>master<\/code> branch, and create a branch from there.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>\ngit clone https:\/\/github.com\/YOUR_USERNAME_HERE\/DefinitelyTyped\ngit checkout -b fix-fav-library-return-type<\/pre>\n<\/div>\n<p>Then we can fix up our library&#8217;s declaration.<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span style=\"color: #BD2C00\">- export function getPerpetualEnergy(): any[];<\/span>\n<span style=\"color: #55A532\">+ export function getPerpetualEnergy(): boolean[];<\/span><\/pre>\n<\/div>\n<p>And fix up <code>my-favorite-library<\/code>&#8216;s test file to make sure our change can be verified:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #00f\">import<\/span> <span class=\"pl-c1\">*<\/span> <span style=\"color: #00f\">as<\/span> <span class=\"pl-smi\">lib<\/span> <span style=\"color: #00f\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>my-favorite-library<span class=\"pl-pds\">\"<\/span><\/span>;\n\n<span style=\"color: #148A14\">\/\/ Notice we added a type annotation to 'energy' so TypeScript could check it for us.<\/span>\n<span style=\"color: #00f\">const<\/span> energy<span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">boolean<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">lib<\/span>.<span class=\"pl-en\">getPerpetualEnergy<\/span>()[<span style=\"color: #09885A\">14<\/span>];\n\n<span class=\"pl-smi\">lib<\/span>.<span class=\"pl-en\">endWorldHunger<\/span>(<span style=\"color: #00f\">true<\/span>);<\/pre>\n<\/div>\n<h2>Dependency Management<\/h2>\n<p>Many packages in the <code>@types<\/code> repo will end up depending on other type declaration packages. For instance, the declarations for <code>react-dom<\/code> will import <code>react<\/code>. By default, writing a declaration file that imports any library in DefinitelyTyped will automatically create a dependency for the <em>latest<\/em> version of that library.<\/p>\n<p>If you want to snap to some version, you can make an explicit <code>package.json<\/code> for the package you&#8217;re working in, and fill in the list of dependencies explicitly. For instance, the declarations for leaflet-draw <a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\/blob\/1a5a11e8f1de7c25c3fb254f0d2677ccf2550bf8\/leaflet-draw\/package.json\">depend on the the <code>@types\/leaflet<\/code> package<\/a>. Similarly, the Twix declarations package <a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\/blob\/1a5a11e8f1de7c25c3fb254f0d2677ccf2550bf8\/twix\/package.json\">has a dependency on <code>moment<\/code> itself<\/a> (since Moment 2.14.0 now ships with declaration files).<\/p>\n<p>As a note, only the <code>dependencies<\/code> field <code>package.json<\/code> is necessary, as the DefinitelyTyped infrastructure will provide the rest.<\/p>\n<h2>Quicker Scaffolding with dts-gen<\/h2>\n<p>We realize that for some packages writing out every function in the API an be a pain. Thats why we wrote <a href=\"https:\/\/github.com\/Microsoft\/dts-gen\">dts-gen<\/a>, a neat tool that can quickly scaffold out declaration files fairly quickly. For APIs that are fairly straightforward, dts-gen can get the job done.<\/p>\n<p>For instance, if we wanted to create declaration files for the <a href=\"https:\/\/www.npmjs.com\/package\/array-uniq\">array-uniq<\/a> package, we could use dts-gen intsead of DefinitelyTyped&#8217;s <code>new-package<\/code> script. We can try this our by installing dts-gen:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>\nnpm install -g dts-gen<\/pre>\n<\/div>\n<p>and then creating the package in our DefinitelyTyped clone:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>cd .\/DefinitelyTyped\nnpm install array-uniq\n\ndts-gen -d -m array-uniq<\/pre>\n<\/div>\n<p>The <code>-d<\/code> flag will create a folder structure like DefinitelyTyped&#8217;s <code>new-package<\/code> script. You can peek in and see that dts-gen figured out the basic structure on its own:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #00f\">export<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">array_uniq<\/span>;\n<span style=\"color: #00f\">declare<\/span> <span style=\"color: #00f\">function<\/span> array_uniq(<span class=\"pl-v\">arr<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">any<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #00f\">any<\/span>;<\/pre>\n<\/div>\n<p>You can even try this out with something like TypeScript itself!<\/p>\n<p>Keep in mind dts-gen doesn&#8217;t figure out <em>everything<\/em> &#8211; for example, it typically substitutes parameter and return values as <code>any<\/code>, and can&#8217;t figure out which parameters are optional. It&#8217;s up to you to make a quality declaration file, but we&#8217;re hoping dts-gen can help bootstrap that process a little better.<\/p>\n<p>dts-gen is still in early experimental stages, but <a href=\"https:\/\/github.com\/Microsoft\/dts-gen\">is on GitHub<\/a> and we&#8217;re looking feedback and contributions!<\/p>\n<h2>\nA Note About Typings, tsd, and DefinitelyTyped Branches<\/h2>\n<p>If you&#8217;re not using tools like <a href=\"https:\/\/www.npmjs.com\/package\/tsd\">tsd<\/a> or <a href=\"https:\/\/www.npmjs.com\/package\/typings\">Typings<\/a>, you can probably skip this section. If you&#8217;ve sent pull requests to DefinitelyTyped recently, you might have heard about a branch on DefinitelyTyped called <code>types-2.0<\/code>. The <code>types-2.0<\/code> branch existed so that infrastructure for <code>@types<\/code> packages wouldn&#8217;t interfere with other tools.<\/p>\n<p>However, this was a source of confusion for new contributors and so we&#8217;ve merged <code>types-2.0<\/code> with <code>master<\/code>. The short story is that all new packages should be sent to the <code>master<\/code> branch, which now must be structured for for TypeScript 2.0+ libraries.<\/p>\n<p>Tools like tsd and Typings will continue to install existing packages that are locked on specific revisions.<\/p>\n<h2>Next Steps<\/h2>\n<p>Our team wants to make it easier for our community to use TypeScript and help out on DefinitelyTyped. Currently we have <a href=\"http:\/\/www.typescriptlang.org\/docs\/handbook\/declaration-files\/publishing.html\">our guide on Publishing<\/a>, but going forward we&#8217;d like to cover more of this information on our website proper.<\/p>\n<p>We&#8217;d also like to hear about resources you&#8217;d like to see improved, and information that isn&#8217;t obvious to you, so feel free to leave your feedback below.<\/p>\n<p>Hope to see you on DefinitelyTyped. Happy hacking!<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A while back we talked about how TypeScript 2.0 made it easier to grab declaration files for your favorite library. Declaration files, if you&#8217;re not familiar, are just files that describe the shape of an existing JavaScript codebase to TypeScript. By using declaration files (also called .d.ts files), you can avoid misusing libraries and get [&hellip;]<\/p>\n","protected":false},"author":381,"featured_media":1797,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-915","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>A while back we talked about how TypeScript 2.0 made it easier to grab declaration files for your favorite library. Declaration files, if you&#8217;re not familiar, are just files that describe the shape of an existing JavaScript codebase to TypeScript. By using declaration files (also called .d.ts files), you can avoid misusing libraries and get [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/users\/381"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/comments?post=915"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/915\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media\/1797"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media?parent=915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}