BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News TypeScript 2.3 Adds Generic Default Arguments, Async Iterators Support, and More

TypeScript 2.3 Adds Generic Default Arguments, Async Iterators Support, and More

TypeScript 2.3 extends the language syntax by adding support for declaring defaults for generic type parameters and for async generators and iterators. It also aims to improve integration with existing JavaScript code with a new compile option and introduces official support for language server plugins.

Generic parameter defaults make TypeScript generics syntax more flexible, similarly to defaults for function parameters. For example, say you have a generic function that supports three different ways of calling it:

declare function create(): Container<HTMLDivElement, HTMLDivElement[]>;
declare function create<T extends HTMLElement>(element: T): Container<T, T[]>;
declare function create<T extends HTMLElement, U extends HTMLElement>(element: T, children: U[]): Container<T, U[]>;

This can now be expressed more succinctly as:

declare function create<T extends HTMLElement = HTMLDivElement, U = T[]>(element?: T, children?: U): Container<T, U>;

A similar set of rules hold for generic parameter defaults as for function parameter defaults, such as not being allowed to define a required parameter after a default/optional one; ensuring defaults satisfy any constraints on type parameters, etc.

Besides being now able to compile generators and iterators to ES3 and ES5 targets when using the --downlevelIteration compile flag, TypeScript 2.3 also adds support for async iterators and generators. Async iterators are similar to non-async iterators in that they provide three methods: next, return, and throw, the only difference being that async iterators return a Promise rather than the actual result:

interface AsyncIterator<T> {
  next(value?: any): Promise<IteratorResult<T>>;
  return?(value?: any): Promise<IteratorResult<T>>;
  throw?(e?: any): Promise<IteratorResult<T>>;
}

Based on iterators, async generators are async functions that can yield partial computation results:

async function* g() {
  yield 1;
  await sleep(100);
  yield* [2, 3];
  yield* (async function *() {
    await sleep(100);
    yield 4;
  })();
}

Related to async iterators and generators, TypeScript 2.3 also introduces for..await..of, which resembles the non-async for..of statement:

async function f() {
  for await (const x of g()) {
     console.log(x);
  }
}

Async iterators and generators support, including for..await..of is opt-in and requires to include esnext in your --lib options.

A new compile option aims to make it easier to work with legacy JavaScript code. Specifically, the new --checkJs flag will make the TypeScript compiler report errors for .js files, too. This allows to catch as many errors as possible without forcing developers to convert their files to .ts. The --checkJs setting can be overridden on a file-by-file basis using the // @ts-nocheck or //@ts-check comments. TypeScript type annotations are not allowed in .js files, but JDoc-style annotations are supported to allow for a progressive transition to TypeScript.

Still on the front of compile options, the new --strict flag aims to make it easier for developers to choose the highest level of type safety available. Used by default in all new projects created by tsc --init, --strict is currently equivalent to:

  • --strictNullChecks
  • --noImplicitAny
  • --noImplicitThis
  • --alwaysStrict

As a final note, TypeScript 2.3 introduces a language server plugin API aimed to augment the support TypeScript already provides to editors for advanced features such as auto-completion by including template systems such as Angular and other types of contents, including TSLint, and GraphQL.

Rate this Article

Adoption
Style

BT