Headshot of Marius Schulz
Marius Schulz Front End Engineer

TypeScript 2.0: Built-In Type Declarations

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 post is part of the TypeScript Evolution series:

  1. TypeScript 2.0: Non-Nullable Types
  2. TypeScript 2.0: Control Flow Based Type Analysis
  3. TypeScript 2.0: Acquiring Type Declaration Files
  4. TypeScript 2.0: Read-Only Properties
  5. TypeScript 2.0: Tagged Union Types
  6. TypeScript 2.0: More Literal Types
  7. TypeScript 2.0: The never Type
  8. TypeScript 2.0: Built-In Type Declarations
  9. TypeScript 2.1: async/await for ES3/ES5
  10. TypeScript 2.1: External Helpers Library
  11. TypeScript 2.1: Object Rest and Spread
  12. TypeScript 2.1: keyof and Lookup Types
  13. TypeScript 2.1: Mapped Types
  14. TypeScript 2.1: Improved Inference for Literal Types
  15. TypeScript 2.1: Literal Type Widening
  16. TypeScript 2.1: Untyped Imports
  17. TypeScript 2.2: The object Type
  18. TypeScript 2.2: Dotted Properties and String Index Signatures
  19. TypeScript 2.2: Null-Checking for Expression Operands
  20. TypeScript 2.2: Mixin Classes
  21. TypeScript 2.3: Generic Parameter Defaults
  22. TypeScript 2.3: The --strict Compiler Option
  23. TypeScript 2.3: Type-Checking JavaScript Files with --checkJs
  24. TypeScript 2.3: Downlevel Iteration for ES3/ES5
  25. TypeScript 2.4: String Enums
  26. TypeScript 2.4: Weak Type Detection
  27. TypeScript 2.4: Spelling Correction
  28. TypeScript 2.4: Dynamic import() Expressions
  29. TypeScript 2.5: Optional catch Binding
  30. TypeScript 2.6: JSX Fragment Syntax
  31. TypeScript 2.7: Numeric Separators
  32. TypeScript 2.7: Strict Property Initialization
  33. TypeScript 2.8: Per-File JSX Factories
  34. TypeScript 2.8: Conditional Types
  35. TypeScript 2.8: Mapped Type Modifiers