Description
In TypeScript 2.0, we want to make acquiring declaration files easier. We'd like to consolidate .d.ts
management with general dependency management through npm.
Background
TypeScript uses declaration files (files ending in .d.ts
, also called "definition" files) to describe the shape and functionality of other libraries. Usually, new declaration files are submitted to DefinitelyTyped, a community-driven repository of declaration files. Unfortunately, there are issues with the way a definition file gets from there to your project today.
Once a declaration file is on DefinitelyTyped, you can get it through tools like Typings or tsd - package managers for declaration files. While very useful, these were extra tools to learn, and this added friction for new users. There were also some technical issues, such as lack of versioning and conflicting declarations, that existing tools couldn't manage.
The new world
So let's jump to the new world to contrast against the current one. Grabbing a declaration file won't require using tsd or Typings at all. It's just an npm command away:
npm install --save @types/lodash
That command does two things:
- Grabs the declaration files for lodash and saves it to a directory named
@types/lodash
in our package'snode_modules
. - Saves that as a dependency in our
package.json
.
@types/lodash
is nothing more than a scoped package. We have taken the time to import files from DefinitelyTyped into their own scoped package. But why does this matter, and why is it any different from how things worked before?
Well in TypeScript 2.0, this @types
folder is going to be significant. Usually when we try to try to import "lodash"
, we look in ./node_modules/lodash
, ../node_modules/lodash
, ../../node_modules/lodash
, etc. for type declarations. Instead, each time we peek into a node_modules
folder as we climb up, we'll look for @types/lodash
first, and then for lodash
.
That might sound surprising, but the logic is that if the lodash
package itself had type declarations, you wouldn't have installed @types/lodash
.
Global declaration files
Some declaration files only affect the globals, and don't use modules (e.g. Jasmine). In most cases, TypeScript will automatically pick them up from the typeRoots
option. By default, typeRoots
will just be node_modules/@types/
and node_modules/
, relative to a tsconfig.json
or for loose files, the files themselves.
If for some reason, you need to include Jasmine but it's not present in your typeRoots
, then you can use the types
compiler option to trigger the same sort of resolution that happens for modules, where TypeScript will look in ./node_modules/@types/
, ./node_modules
, and keep climbing up.
The types
option could be used something like this.
{
"compilerOptions": {
"types": ["jasmine"]
}
}
Going forward
Library authors will be getting attention in 2.0 as well. We're also introducing new features that simplify the way .d.ts
files can be authored for libraries that are both modules and globally defined (also called universal modules). Apart from that, everything stays the same - for instance, new declarations and fixes should still go to DefinitelyTyped. In the future, we'll go into this in more detail and have some prescriptive documentation.
Acknowledgements
We also owe a great thanks to those who dedicated their own time into efforts like Typings and tsd.
These tools helped bring TypeScript where it is today and ultimately helped guide us on the direction for this effort. Specifically, Blake Embrey, the maintainer and creator of Typings, has worked closely with us during this entire process and given us extremely valuable feedback. In addition to this, Diullei Gomes and Bart van der Schoor, maintainers of tsd, have helped lay the foundation from the beginning.
Finally, the entire DefinitelyTyped community - a group that has grown to over 2000 contributors at this point - have demonstrated, and continue to show, the kind of enthusiasm and support outside of the core team. We're grateful for all the great work that's been done here.