Marius Schulz
Marius Schulz
Front End Engineer

Built-In Type Declarations in TypeScript

TypeScript 2.0 gives you more granular control over which built-in API declarations to include in your project. Previously, you were only able to access ES2015 APIs if your project was targeting ES6. Now, the built-in standard library declarations have been modularized, and TypeScript allows you to pick and choose which type declarations to include.

#The --lib Compiler Option

The type declarations for the JavaScript standard library have been partitioned into a bunch of API groups. At the time of writing in late November 2016, the following groups are defined:

  • dom
  • webworker
  • es5
  • es6 / es2015
  • es2015.core
  • es2015.collection
  • es2015.iterable
  • es2015.promise
  • es2015.proxy
  • es2015.reflect
  • es2015.generator
  • es2015.symbol
  • es2015.symbol.wellknown
  • es2016
  • es2016.array.include
  • es2017
  • es2017.object
  • es2017.sharedmemory
  • scripthost

You can pass any subset of the above groups to the TypeScript compiler via the --lib command line option or the lib property in your tsconfig.json. TypeScript will then only inject the typings you specified; that is, it will treat all other API groups as non-existent in your environment.

If you don't explicitly provide the lib option, TypeScript will implicitly inject a selection of API groups needed for web development. These are the defaults, depending on which language level your project targets:

  • ["dom", "es5", "scripthost"] when targeting ES5
  • ["dom", "es6", "dom.iterable", "scripthost"] when targeting ES6

#Using ES2015 Promises in a TypeScript Project Targeting ES5

Let's say you're working on a web project that targets ES5 so that it runs in all major browsers. Your tsconfig.json could look like this:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

Since the lib option is not specified, TypeScript will inject the API groups "dom", "es5", and "scripthost" by default. Now let's assume you want to use native ES2015 promises in your project. Those didn't exist in ES5, so you need to install a polyfill to make your code run in older browsers as well:

npm install --save es6-promise

You then import the polyfill in your application's entry module:

import "es6-promise";

// ...

With this polyfill in place, you can now use Promise in your application, and your code will run just fine. However, TypeScript will give you a compile-time error saying that it Cannot find the name 'Promise'. That's because the type declarations for Promise aren't included in any of the API groups injected:

Missing type declaration for native ES2015 promises

You have to let TypeScript know that (because of your polyfill) Promise will exist at runtime. That's where the lib compiler option comes into play:

API groups for built-in type declarations

Note that you have to explicitly provide all API groups once you're overriding the default. The resulting tsconfig.json now looks like this:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "noImplicitAny": true,
    "strictNullChecks": true,
    "lib": ["dom", "es5", "es2015.promise"]
  }
}

And that's it! Now, the type checker is happy:

Using native ES2015 promises in TypeScript

This article and 44 others are part of the TypeScript Evolution series. Have a look!