Announcing TypeScript 2.2 RC

Daniel Rosenwasser

TypeScript 2.2 is just around the corner, and today we’re announcing its release candidate!

If you’re first hearing about it, TypeScript is a language that just takes JavaScript and adds optional static types. Being built on JavaScript means that you don’t have to learn much more beyond what you know from JavaScript, and all your existing code continues to work with TypeScript. Meanwhile, the optional types that TypeScript adds can help you catch pesky bugs and work more efficiently by enabling great tooling support.

To try out the RC today, you can use NuGet, or using npm just run

npm install -g typescript@rc

You can also get the TypeScript release candidate for Visual Studio 2015 (if you have Update 3). Other built-in editor support will be coming with our proper 2.2 release, but you can look at guides on how to enable newer versions of TypeScript in Visual Studio Code and Sublime Text 3.

To clue you in on what’s new, here’s a few noteworthy features to get an idea about what to keep an eye out for in this release candidate.

The object type

There are times where an API allows you to pass in any sort of value except for a primitive. For example, consider Object.create, which throws an exception unless you pass in an object or null for its first argument.

// All of these throw errors at runtime!
Object.create(undefined);
Object.create(1000);
Object.create("hello world");

If we try to come up with the type of the first parameter, a naive approach might be Object | null. Unfortunately, this doesn’t quite work. Because of the way that structural types work in TypeScript, number, string, and boolean are all assignable to Object.

To address this, we’ve created the new object type (and notice all of those lowercase letters!). A more obvious name might be the “non-primitive” type.

The object type is “empty” – it has no properties just like the {} type. That means that almost everything is assignable to object except for primitives. In other words, number, boolean, string, symbol, null, and undefined won’t be compatible.

But that means that we can now correctly type Object.create‘s first parameter as object | null!

We anticipate that the object primitive type will help catch a large class of bugs, and more accurately model real world code.

We owe a big thanks to Herrington Darkholme for lending a hand and implementing this feature!

Improved support for mixins and composable classes

The mixin pattern is fairly common in the JavaScript ecosystem, and in TypeScript 2.2 we’ve made some adjustments in the language to supporting it even better.

To get this done, we removed some restrictions on classes in TypeScript 2.2, like being able to extend from a value that constructs an intersection type. It also adjusts some functionality in the way that signatures on intersection types get combined. The result is that you can write a function that

  1. takes a constructor
  2. declares a class that extends that constructor
  3. adds members to that new class
  4. and returns the class itself.

For example, we can write the Timestamped function which takes a class, and extends it by adding a timestamp member.

/** Any type that can construct *something*. */
export type Constructable = new (...args: any[]) => {};

export function Timestamped<BC extends Constructable>(Base: BC) {
    return class extends Base {
        timestamp = new Date();
    };
}

Now we can take any class and pass it through Timestamped to quickly compose a new type.

class Point {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

const TimestampedPoint = Timestamped(Point);

const p = new TimestampedPoint(10, 10);
p.x + p.y;
p.timestamp.getMilliseconds();

Similarly, we could write a Tagged function which adds a tag member. These functions actually make it very easy to compose extensions. Making a special 3D point that’s tagged and timestamped is pretty clean.

class SpecialPoint extends Tagged(Timestamped(Point)) {
    z: number;
    constructor(x: number, y: number, z: number) {
        super(x, y);
        this.z = z;
    }
}

A new JSX emit mode: react-native

In TypeScript 2.1 and earlier, the --jsx flag could take on two values:

  • preserve which leaves JSX syntax alone and generates .jsx files.
  • react which transforms JSX into calls to React.createElement and generates .js files.

TypeScript 2.2 has a new JSX emit mode called react-native which sits somewhere in the middle. Under this scheme, JSX syntax is left alone, but generates .js files.

This new mode accomodates React Native’s loader which expects all input files to be .js files. It also satisfies cases where you want to just leave your JSX syntax alone but get .js files out from TypeScript.

What’s next for 2.2?

While we can’t list everything that we’ve worked on here on this post, you can see what else we have in store here on the TypeScript Roadmap.

We’re counting on your feedback to make TypeScript 2.2 a solid release! Please feel free to leave us feedback here, or file an issue on GitHub if you run into anything you may think is a bug.

0 comments

Discussion is closed.

Feedback usabilla icon