For those who haven’t yet heard of it, TypeScript is a simple extension to JavaScript to add optional types along with all the new ECMAScript features. TypeScript builds on the ECMAScript standard and adds type-checking to make you way more productive through cleaner code and stronger tooling. Your TypeScript code then gets transformed into clean, runnable JavaScript that even older browsers can run.
While there are a variety of ways to get TypeScript set up locally in your project, the easiest way to get started is to try it out on our site or just install it from npm:
npm install -g typescript
If you’re a Visual Studio 2015 user with update 3, you can install TypeScript 2.2 from here. You can also grab this release through NuGet. Support in Visual Studio 2017 will come in a future update.
If you’d rather not wait for TypeScript 2.2 support by default, you can configure Visual Studio Code and our Sublime Text plugin to pick up whatever version you need.
As usual, we’ve written up about new features on our what’s new page, but we’d like to highlight a couple of them.
More quick fixes
One of the areas we focus on in TypeScript is its tooling – tooling can be leveraged in any editor with a plugin system. This is one of the things that makes the TypeScript experience so powerful.
With TypeScript 2.2, we’re bringing even more goodness to your editor. This release introduces some more useful quick fixes (also called code actions) which can guide you in fixing up pesky errors. This includes
- Adding missing imports
- Adding missing properties
- Adding forgotten
this.to variables - Removing unused declarations
- Implementing abstract members
With just a few of these, TypeScript practically writes your code for you.
As you write up your code, TypeScript can give suggestions each step of the way to help out with your errors.
Expect similar features in the future. The TypeScript team is committed to ensuring that the JavaScript and TypeScript community gets the best tooling we can deliver.
With that in mind, we also want to invite the community to take part in this process. We’ve seen that code actions can really delight users, and we’re very open to suggestions, feedback, and contributions in this area.
The object type
The object type is a new type in 2.2 that matches any types except for primitive types. In other words, you can assign anything to the object type except for string, boolean, number, symbol, and, when using strictNullChecks, null and undefined.
object is distinct from the {} type and Object types in this respect due to structural compatibility. Because the empty object type ({}) also matches primitives, it couldn’t model APIs like Object.create which truly only expect objects – not primitives. object on the other hand does well here in that it can properly reject being assigned a number.
We’d like to extend our thanks to members of our community who proposed and implemented the feature, including François de Campredon and Herrington Darkholme.
Easier string indexing behavior
TypeScript has a concept called index signatures. Index signatures are part of a type, and tell the type system what the result of an element access should be. For instance, in the following:
interface Foo {
// Here is a string index signature:
[prop: string]: boolean;
}
declare const x: Foo;
const y = x["hello"];
Foo has a string index signature that says “whenever indexing with a string, the output type is a boolean.” The core idea is that index signatures here are meant to model the way that objects often serve as maps/dictionaries in JavaScript.
Before TypeScript 2.2, writing something like x["propName"] was the only way you could make use of a string index signature to grab a property. A little surprisingly, writing a property access like x.propName wasn’t allowed. This is slightly at odds with the way JavaScript actually works since x.propName is semantically the same as x["propName"]. There’s a reasonable argument to allow both forms when an index signature is present.
In TypeScript 2.2, we’re doing just that and relaxing the old restriction. What this means is that things like testing properties on a JSON object has become dramatically more ergonomic.
interface Config {
[prop: string]: boolean;
}
declare const options: Config;
// Used to be an error, now allowed!
if (options.debugMode) {
// ...
}
Better class support for mixins
We’ve always meant for TypeScript to support the JavaScript patterns you use no matter what style, library, or framework you prefer. Part of meeting that goal involves having TypeScript more deeply understand code as it’s written today. With TypeScript 2.2, we’ve worked to make the language understand the mixin pattern.
We made a few changes that involved loosening some restrictions on classes, as well as adjusting the behavior of how intersection types operate. Together, these adjustments actually allow users to express mixin-style classes in ES2015, where a class can extend anything that constructs some object type. This can be used to bridge ES2015 classes with APIs like Ember.Object.extend.
As an example of such a class, we can write the following:
type Constructable = new (...args: any[]) => object;
function Timestamped<BC extends Constructable>(Base: BC) {
return class extends Base {
private _timestamp = new Date();
get timestamp() {
return this._timestamp;
}
};
}
and dynamically create classes
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
const TimestampedPoint = Timestamped(Point);
and even extend from those classes
class SpecialPoint extends Timestamped(Point) {
z: number;
constructor(x: number, y: number, z: number) {
super(x, y);
this.z = z;
}
}
let p = new SpecialPoint(1, 2, 3);
// 'x', 'y', 'z', and 'timestamp' are all valid properties.
let v = p.x + p.y + p.z;
p.timestamp.getMilliseconds()
The react-native JSX emit mode
In addition to the preserve and react options for JSX, TypeScript now introduces the react-native emit mode. This mode is like a combination of the two, in that it emits to .js files (like --jsx react), but leaves JSX syntax alone (like --jsx preserve).
This new mode reflects React Native’s behavior, which expects all input files to be .js files. It’s also useful for cases where you want to just leave your JSX syntax alone but get .js files out from TypeScript.
Support for new.target
With TypeScript 2.2, we’ve implemented ECMAScript’s new.target meta-property. new.target is an ES2015 feature that lets constructors figure out if a subclass is being constructed. This feature can be handy since ES2015 doesn’t allow constructors to access this before calling super().
What’s next?
Our team is always looking forward, and is now hard at work on TypeScript 2.3. While our team’s roadmap should give you an idea of what’s to come, we’re excited for our next release, where we’re looking to deliver
- default types for generics
- async iterator support
- downlevel generator support
Of course, that’s only a preview for now.
We hope TypeScript 2.2 makes you even more productive, and allows you to be even more expressive in your code. Thanks for taking the time to read through, and as always, happy hacking!

Daniel, do you have an example of mixins which doesn’t rely on inheritance? I wouldn’t necessarily think of this example as a typical mixin scenario, but rather dynamic class definitions. Is it possible with the new capabilities to mix properties and methods in without changing the inheritance hierarchy? and get the strong typing/intellisense?
Hey Rob, there’s two scenarios I think you might be referring to. If you want to simply create a new class whose prototype is merged from several other types (but not necessarily inherit from any of them), check out http://bit.ly/2l9niCW. Otherwise, you might be looking for a way to add methods to a class’ prototype after the fact, you can “reopen” the type by using class/interface merging. Check out http://bit.ly/2mdhv0f if that’s the case.
That’s nice indeed! what is not so nice is lack of decorator support. Me and my team personally prefer decorators over mixins but as it turns out it isn’t possible to extends Class definition with them, although when used as function wrapper everything works!
Demo:
https://goo.gl/HPqd6o
Any suggestions?
Btw terrific job with new release! thx a lot guys 🙂
Hey, Daniel, thanks for the examples! Sorry for the noobish questions (I’m quite new to TS), but how can I mix an arbitrary number of classes? I couldn’t get it working with `extend(extend(A, B), C)`. I tried `reduce`ing a list of classes like this:
`
function extend(…classes) {
return classes.reduce(function (mixed: Constructor & ST, mixin: Constructor & SU) {
Object.assign(mixed, mixin);
Object.assign(mixed.prototype, mixin.prototype);
return mixed as Constructor & ST & SU;
}, class { });
}
`
It seems to work, but at the cost of having to leave the argument type as `any`. Am I doing it right?
Another (noobish) question: Are `propA` and `propB` supposed to be left out of the result? They don’t make it to the “mixed” class even if I declare a constructor (eg. `constructor(propA: number) { this.propA = propA }`).
Thanks in advance!
I still prefer this way to have mixin…
https://medium.com/@danny_mylian/mixins-as-class-decorators-in-typescript-angular2-8e09f1bc1f02#.hd68a7t2j
Question, when will I be able to do something like this:
interface Point {
x:number;
y:number;
}
let pointData = {x:12, y:45}; // fetched from a REST API for example
let myPoint = {…point}
I am not sure i understand the request. Object spread operator is already supported as of TypeScript 2.1.
Great work!
Love the new mixin design! Amazing work. But I can’t use property / method decorators? 🙁
Logged here https://github.com/Microsoft/TypeScript/issues/7342
It looks like from the animation that there’s a keybinding for bringing up the dropdown for adding missing imports, etc. What is it? 🙂
In VSCode the shortcut is Ctrl+.
“Support in Visual Studio 2017 will come in a future update”.
Which would be when? RTM on March 7? Update to the RC?
Seriously… when? VS 2017 installed and just waiting to install latest TypeScript.
Unfortunately “Visual Studio 2017 ships with a built in version of TypeScript. The current version is TS2.1. Newer versions of TS will be available throughout the VS update vehicles in the future; and will not be available as out of band installers like in VS2015 and VS2013.” – Mohamed Hegazy
See https://github.com/Microsoft/TypeScript/issues/14529
What? Looks like I’m rolling back to 2015 🙁
Well great. I’m rolling back to 2015. That’s ridiculous.
> object is distinct from the {} type and Object types
I think TypeScript books will sell quite well given enough time.
Great work!
Should the new Quick Fixes work with the current version of VSCode (1.9.1)?
If so, could you describe steps to make the “Adding missing imports” Quick Fix work?
Quick fixes will be exposed in the next version of VS Code, and Ctrl+. is the shortcut key to use them. They will appear as an option when your cursor sits over an error with a quickfix.
I would love an option to not allow raw JavaScript code in my TypeScript. IMO, the default should be to not allow mixed TypeScript/JavaScript in my TypeScript files. However, the ability to set this with a config setting would work just as well.
As always, this is the most brilliant thing in web development. Thank you. Looking forward to 2.3 already.
Oops, obviously that’s not meant as a reply to Jeffery P.
But while I’m here… what is raw JavaScript code and why don’t you want it in your TypeScript?
TypeScript is a superset of JavaScript so all JavaScript _is_ TypeScript.
but not all Javascript is COMPILABLE Typescript
Installed the latest release for Visual Studio 2015, but do not see Quick Fixes. Are they supposed to work in it? If not, will they?
Quick fixes are only available in VSCode (1.10), and in the next release of VS 2017. They are not supported in VS 2015 at the time being.
Hi,
I love the changes, great work! I was checking TS2.2 locally in VSCode and was wondering whether it’s possible to make the “adding missing imports” quick fix work when the module system is set to none?
Example:
common.ts:
module MyCompany.MyApplication.Module.Common {
export class ArgumentParser {
public name: string;
}
}
main.ts:
module MyCompany.MyApplication.Module.Main {
var argumentParser = new SharedClass();
}
SharedClass gets marked as an error in main.ts and Ctrl+. should offer to add import SharedClass = MyCompany.MyApplication.Module.Common.SharedClass; just above it.
Is this intentionally left out?
The class name should be SharedClass in common.ts.
We haven’t implemented that functionality yet. Recently we’ve had a focus on modules (formerly called “external modules”) rather than namespaces (formerly “internal modules”).
Thanks a lot for the fantastic work guys !
Typescript and VSCode are what reconciled me with JavaScript and web development in general.
It’s improving each day, and in very smart ways IMHO.
Keep the awesomeness going !
No auto imports in vs2015 ?
You guys really do a great job!
Great work but pleeease add VS 2017 support for Quick Fixes
I guess quality is still job SP1.
This new indexing behavior makes me sad.
In Typescript, I take foo[“bar”] as meaning “I think the variable foo has a bar property, but I’m not sure”, or “dynamically access the property bar of foo”.
I take foo.bar as meaning “I’m sure the variable foo has a bar property – and if I’m wrong, I expect you to tell me”, or “statically access the property bar of foo”.
You just broke that 🙁
What an idiot you should be to announce whone new Visual Studio 2017 that can’t support latest Typescrpt (2.2 released 2 month ago, 2.3 is RC) because it is HARDCODED??? MS in it’s own style…
How to export mixin class? The following code
export type Constructor = new(…args: any[]) => T;
export default
(Superclass: S) => class Pluggable extends Superclass {…}generates this error
error TS4082: Default export of the module has or is using private name ‘Pluggable’.