Featured image of post Built-In Type Declarations in TypeScript

Built-In Type Declarations in TypeScript

Overview

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:

1
2
3
4
5
6
7
8
{
  "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:

In web development, a polyfill (or polyfiller) is downloadable code which provides facilities { 设施;工具 } that are not built into a web browser. For example, many features of HTML5 are not supported by versions of Internet Explorer older than version 8 or 9, but can be used by web pages if those pages install a polyfill.

1
npm install --save es6-promise

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

1
2
3
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:

1
2
3
4
5
6
7
8
9
{
  "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

References

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy