The typescript compiler can be configured via tsconfig.json
. This also offers settings for discovering type definition files with the typeRoots
key.
By default:
By default all visible “@types” packages are included in your
compilation. Packages in node_modules/@types of any enclosing folder
are considered visible; specifically, that means packages within
./node_modules/@types/, ../node_modules/@types/,
../../node_modules/@types/, and so on.
If typeRoots is specified, only packages under typeRoots will be
included
Many packages offer their type definitions in a separate @types/<package-name>
package. Jquery for example.
At the same time, there are packages that ship with bundled type definitions, Firebase does this.
Why can the typescript compiler pick up Firebase definitions without editing the typeRoots
setting? These definitions are not located in @types and, as far as I understand, should not be picked up by default.
In the publishing docs in TypeScript you see there are two ways to provide types for your users: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html
- bundling with your npm package, or
- publishing to the @types organization on npm.
Bigger libraries like Firebase have their own types, see
packages/firebase/package.json#L58 or packages/database/package.json#L68.
Typescripts reads those referenced files in "typings"
of all installed packages that are referenced in your code that is being compiled.
The difference between typeRoots
and a regular import 'firebase'
is :
Once you provide type files in typeRoot those types are always used in the compilation process (automatic inclusion). This is great for libraries the change the global context, like jQuery, node, etc. They provide global functions that could otherwise not easily be picked up.
You import it explicitly by saying import {Foo} from 'bar'
. If bar
package has a typing
property in its package.json, Typescript will pick it up additionally to those in typeRoots.
The documentation says this:
Keep in mind that automatic inclusion is only important if you’re using files with global declarations (as opposed to files declared as modules). If you use an import "foo" statement, for instance, TypeScript may still look through node_modules & node_modules/@types folders to find the foo package.