Typescript 2.0. "types" field in tsconfig.json
TypescriptTypescript Typingstypescript2.0Typescript Problem Overview
I do not understand the meaning of types
field in tsconfig.json
. In documentation I have read such text:
"types": {
"description": "Type declaration files to be included in compilation. Requires TypeScript version 2.0 or later.",
"type": "array",
"items": {
"type": "string"
}
},
As far, as I understand if I install @types/express
I should add such string in tsconfig.json
{
"compilerOptions": {
...
"types": ["lodash"]
}
}
but everything works fine without it. And now I do not understand, why I need types
field
Typescript Solutions
Solution 1 - Typescript
As of TypeScript 2.* the 'tsconfig.json' has the following two properties available:
{
'typeRoots': [],
'types': []
}
I'll detail both in order.
- 'typeRoots' specifies root folders in which the transpiler should look for type definitions (eg: 'node_modules').
-
If you've been using typescript, you know that for different libraries that have not been written using typescript, you need definitions in order for the compiler to recognize global variables and to have IntelliSense support.
-
This issue has been tackled by projects (repos) such as 'DefinatelyTyped' that use tools such as tsd or typings module to download typings required for your project, but they also come with their own 'json' file that needs to be maintained separately.
-
With TS2.* you can now fetch definition dependencies using 'npm'. So instead of using a seperate cli library like tsd or typings, you can now just use:
npm i @types/{LIB}
this way, all dependencies are managed using package.json and you can easily eliminate the necessity of another 'json' file to maintain in your project.
- 'types' are the actual library names that will be found in the typeRoot.
-
so let's say you have the default configuration for typeRoots which would look something like:
"typeRoots": [ "./node_modules/@types" ]
-
let's say you now want to use jasmine as a test framework for your project, so you have your typeRoot folder configured, all you have too do now is execute:
npm i @types/jasmine --save-dev
-
after the definition package is installed you just need to configure your 'types' property in 'tsconfig.json' as follows:
"types": [ "core-js", "jasmine", "requirejs", "chance" ]
To conclude, basically you tell the TS compiler the following:
typeRoots: You need to look for typings in these folders. types: In one of the folders provided above, you will find definitions for theses framworks (subfolders).
So using the scenario above, and if we add another root:
"typeRoots": [
"./node_modules/@types",
"./custom_definitions"
],
"types": [
"jasmine",
]
TS will now look for definition files in
./node_modules/@types/jasmine
or
./custom_definitions/jasmine
Hope this helps!
Solution 2 - Typescript
You don't need the types field necessarily. Here is the important part to note from the documentation:
> By default all visible “@types” packages are included in your > compilation. Packages in node_modules/@types of any enclosing folder > are considered visible
So, if you have followed convention or used a tooling set such as npm to download @types packages, you don't need to configure typeRoots or types in your configuration as it will work out of the box with the default folder structure.
Solution 3 - Typescript
Small addition to other answers: @types property in tsconfig.json is used mostly for global declarations (logic which you can use without import
ing modules). So, it won't limit your types if you import
. E.g. you have this package: node_modules/@types/foo
. And your @types
prop equals to [bar]
. You will discover that this is still working if foo
is a module based logic:
import {A, B, C} from 'foo'
see TS docs:
> 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.