async/await support in ES6 targets (Node v4+)

TypeScript now supports asynchronous functions for engines that have native support for ES6 generators, e.g. Node v4 and above. Asynchronous functions are prefixed with the async keyword; await suspends the execution until an asynchronous function return promise is fulfilled and unwraps the value from the Promise returned.

Example

In the following example, each input element will be printed out one at a time with a 400ms delay:

  1. "use strict";
  2. // printDelayed is a 'Promise<void>'
  3. async function printDelayed(elements: string[]) {
  4. for (const element of elements) {
  5. await delay(400);
  6. console.log(element);
  7. }
  8. }
  9. async function delay(milliseconds: number) {
  10. return new Promise<void>(resolve => {
  11. setTimeout(resolve, milliseconds);
  12. });
  13. }
  14. printDelayed(["Hello", "beautiful", "asynchronous", "world"]).then(() => {
  15. console.log();
  16. console.log("Printed every element!");
  17. });

For more information see async function reference reference.

Support for --target ES6 with --module

TypeScript 1.7 adds ES6 to the list of options available for the --module flag and allows you to specify the module output when targeting ES6. This provides more flexibility to target exactly the features you want in specific runtimes.

Example
  1. {
  2. "compilerOptions": {
  3. "module": "amd",
  4. "target": "es6"
  5. }
  6. }

this-typing

It is a common pattern to return the current object (i.e. this) from a method to create fluent-style APIs. For instance, consider the following BasicCalculator module:

  1. export default class BasicCalculator {
  2. public constructor(protected value: number = 0) {}
  3. public currentValue(): number {
  4. return this.value;
  5. }
  6. public add(operand: number) {
  7. this.value += operand;
  8. return this;
  9. }
  10. public subtract(operand: number) {
  11. this.value -= operand;
  12. return this;
  13. }
  14. public multiply(operand: number) {
  15. this.value *= operand;
  16. return this;
  17. }
  18. public divide(operand: number) {
  19. this.value /= operand;
  20. return this;
  21. }
  22. }

A user could express 2 * 5 + 1 as

  1. import calc from "./BasicCalculator";
  2. let v = new calc(2)
  3. .multiply(5)
  4. .add(1)
  5. .currentValue();

This often opens up very elegant ways of writing code; however, there was a problem for classes that wanted to extend from BasicCalculator. Imagine a user wanted to start writing a ScientificCalculator:

  1. import BasicCalculator from "./BasicCalculator";
  2. export default class ScientificCalculator extends BasicCalculator {
  3. public constructor(value = 0) {
  4. super(value);
  5. }
  6. public square() {
  7. this.value = this.value ** 2;
  8. return this;
  9. }
  10. public sin() {
  11. this.value = Math.sin(this.value);
  12. return this;
  13. }
  14. }

Because TypeScript used to infer the type BasicCalculator for each method in BasicCalculator that returned this, the type system would forget that it had ScientificCalculator whenever using a BasicCalculator method.

For instance:

  1. import calc from "./ScientificCalculator";
  2. let v = new calc(0.5)
  3. .square()
  4. .divide(2)
  5. .sin() // Error: 'BasicCalculator' has no 'sin' method.
  6. .currentValue();

This is no longer the case - TypeScript now infers this to have a special type called this whenever inside an instance method of a class. The this type is written as so, and basically means “the type of the left side of the dot in a method call”.

The this type is also useful with intersection types in describing libraries (e.g. Ember.js) that use mixin-style patterns to describe inheritance:

  1. interface MyType {
  2. extend<T>(other: T): this & T;
  3. }

ES7 exponentiation operator

TypeScript 1.7 supports upcoming ES7/ES2016 exponentiation operators: ** and **=. The operators will be transformed in the output to ES3/ES5 using Math.pow.

Example
  1. var x = 2 ** 3;
  2. var y = 10;
  3. y **= 2;
  4. var z = -(4 ** 3);

Will generate the following JavaScript output:

  1. var x = Math.pow(2, 3);
  2. var y = 10;
  3. y = Math.pow(y, 2);
  4. var z = -Math.pow(4, 3);

Improved checking for destructuring object literal

TypeScript 1.7 makes checking of destructuring patterns with an object literal or array literal initializers less rigid and more intuitive.

When an object literal is contextually typed by the implied type of an object binding pattern:

  • Properties with default values in the object binding pattern become optional in the object literal.
  • Properties in the object binding pattern that have no match in the object literal are required to have a default value in the object binding pattern and are automatically added to the object literal type.
  • Properties in the object literal that have no match in the object binding pattern are an error.

When an array literal is contextually typed by the implied type of an array binding pattern:

  • Elements in the array binding pattern that have no match in the array literal are required to have a default value in the array binding pattern and are automatically added to the array literal type.
Example
  1. // Type of f1 is (arg?: { x?: number, y?: number }) => void
  2. function f1({ x = 0, y = 0 } = {}) {}
  3. // And can be called as:
  4. f1();
  5. f1({});
  6. f1({ x: 1 });
  7. f1({ y: 1 });
  8. f1({ x: 1, y: 1 });
  9. // Type of f2 is (arg?: (x: number, y?: number) => void
  10. function f2({ x, y = 0 } = { x: 0 }) {}
  11. f2();
  12. f2({}); // Error, x not optional
  13. f2({ x: 1 });
  14. f2({ y: 1 }); // Error, x not optional
  15. f2({ x: 1, y: 1 });

Support for decorators when targeting ES3

Decorators are now allowed when targeting ES3. TypeScript 1.7 removes the ES5-specific use of reduceRight from the __decorate helper. The changes also inline calls Object.getOwnPropertyDescriptor and Object.defineProperty in a backwards-compatible fashion that allows for a to clean up the emit for ES5 and later by removing various repetitive calls to the aforementioned Object methods.