Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript 2.0. "types" field in tsconfig.json

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

like image 980
Stalso Avatar asked Oct 03 '16 07:10

Stalso


3 Answers

As of TypeScript 2.* the 'tsconfig.json' has the following two properties available:

{
    'typeRoots': [],
    'types': [] 
}

I'll detail both in order.


  1. '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.


  1. '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!

like image 118
Vlad Jerca Avatar answered Nov 11 '22 16:11

Vlad Jerca


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.

like image 49
Xcalibur Avatar answered Nov 11 '22 16:11

Xcalibur


Small addition to other answers: @types property in tsconfig.json is used mostly for global declarations (logic which you can use without importing 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.

like image 3
Vitaly Avatar answered Nov 11 '22 16:11

Vitaly