Today we’re excited to roll out our beta release of TypeScript 2.0. If you’re not familiar with TypeScript yet, you can start learning it today on our website.
To get your hands on the beta, you can download TypeScript 2.0 Beta for Visual Studio 2015 (which will require VS 2015 Update 3), or just run
npm install -g typescript@beta
This release includes plenty of new features, such as our new workflow for getting .d.ts files, but here’s a couple more features just to get an idea of what else is in store.
Non-nullable Types
null and undefined are two of the most common sources of bugs in JavaScript. Before TypeScript 2.0, null and undefined were in the domain of every type. That meant that if you had a function that took a string, you couldn’t be sure from the type alone of whether you actually had a string – you might actually have null.
In TypeScript 2.0, the new --strictNullChecks flag changes that. string just means string and number means number.
let foo: string = null; // Error!
What if you wanted to make something nullable? Well we’ve brought two new types to the scene: null and undefined. As you might expect, null can only contain null, and undefined only contains undefined. They’re not totally useful on their own, but you can use them in a union type to describe whether something could be null/undefined.
let foo: string | null = null; // Okay!
Because you might often know better than the type system, we’ve also introduced a postfix ! operator that takes null and undefined out of the type of any expression.
declare let strs: string[] | undefined;
// Error! 'strs' is possibly undefined.
let upperCased = strs.map(s => s.toUpperCase());
// 'strs!' means we're sure it can't be 'undefined', so we can call 'map' on it.
let lowerCased = strs!.map(s => s.toLowerCase());
Control Flow Analysis for Types
TypeScript’s support for handling nullable types is possible thanks to changes in how types are tracked throughout the program. In 2.0, we’ve started using control flow analysis to better understand what a type has to be at a given location. For instance, consider this function.
/**
* @param recipients An array of recipients, or a comma-separated list of recipients.
* @param body Primary content of the message.
*/
function sendMessage(recipients: string | string[], body: string) {
if (typeof recipients === "string") {
recipients = recipients.split(",");
}
// TypeScript knows that 'recipients' is a 'string[]' here.
recipients = recipients.filter(isValidAddress);
for (let r of recipients) {
// ...
}
}
Notice that after the assignment within the if block, TypeScript understood that it had to be dealing with an array of strings.
This sort of thing can catch issues early on and save you from spending time on debugging.
let bestItem: Item;
for (let item of items) {
if (item.id === 42) bestItem = item;
}
// Error! 'bestItem' might not have been initialized if 'items' was empty.
let itemName = bestItem.name;
We owe a major thanks to Ivo Gabe de Wolff for his work and involvement in implementing this feature, which started out with his thesis project and grew into part of TypeScript itself.
Easier Module Declarations
Sometimes you want to just tell TypeScript that a module exists, and you might not care what its shape is. It used to be that you’d have to write something like this:
declare module "foo" {
var x: any;
export = x;
}
But that’s a hassle, so we made it easier and got rid of the boilerplate. In TypeScript 2.0 you can just write
declare module "foo";
declare module "bar";
When you’re ready to finally outline the shape of a module, you can come back to these declarations and define the structure you need.
What if you you depend on a package with lots of modules? Writing those out for each module might be a pain, but TypeScript 2.0 makes that easy too by allowing wildcards in these declarations!
declare module "foo/*";
Now you can import any path that starts with foo/ and TypeScript will assume it exists. You can take advantage of this if your module loader understands how to import based on a certain patterns too. For example:
declare module "*!text" {
const content: string;
export = content;
}
Now whenever you import a path ending with !text, TypeScript will understand that the import should be typed as a string.
import text = require("./hello.txt!text");
text.toLowerCase();
Next Steps
One feature you might be wondering about is support for async functions in ES3 & ES5. Originally, this was slated for the 2.0 release; however, to reasonably implement async/await, we needed to rewrite TypeScript’s emitter as a series of tree transformations. Doing so, while keeping TypeScript fast, has required a lot of work and attention to detail. While we feel confident in today’s implementation, confidence is no match for thorough testing, and more time is needed for async/awaitto stabilize. You can expect it in TypeScript 2.1, and if you’d like to track the progress, the pull request is currently open on GitHub.
TypeScript 2.0 is still packed with many useful new features, and we’ll be coming out with more details as time goes on. If you’re curious to hear more about what’s new, you can take a look at our wiki. In the coming weeks, a more stable release candidate will be coming out, with the final product landing not too far after.
We’d love to hear any feedback you have, either in the comments below or on GitHub. Happy hacking!

The only thing I wanted was ES5 async/await, this is what has been holding me back since the beginning. Boo 🙁
Boo indeed. I was anticipating this release for async \ await for many reasons. This WAS on the roadmap for 1.6 from memory and we’re still waiting.
Maybe just delete the roadmap to stop pissing people off when you don’t deliver the major feature a lot of devs have been waiting for. Or at least retrospectively change the roadmap so we have nothing to base our arguments on.
You still can make you own language, here(http://yosbelms.github.io/cor) the mine with async capabilities.
async/await can be used now by targeting ES6 and compiling the result with Babel. It’s inconvenient, but it works fine and using async/await in the browser is a real joy. 🙂
You can also use async/await now now if you use Dart instead. 😀
Does anybody still use Dart?
That one guy at Google
If only google had done a better job advocating Dart. It is a fantastic language
Not having async/await shouldn’t be holding you back. Just use promises.
A call in a for loop that you want to call await on is very hard to do with just promises.
It’s a bit inconvenient but not very hard. You can have an array of promises use a recursive function to loop through it.
I’ve used a reduce function to chain promises together to accomplish that. It reads as well as a FOR OF loop, especially if you can use fat arrow syntax.
Non nullable types are HUGE. Thanks guys.
Pity that async await has missed 2.0 I’ve been waiting for it since October 2012. 🙂
I use async/await in ts since 1.6 or something..
Or you mean async/await for ES5? It’s emulated by ES6 generators now.
+1 for all the new features, and especially the improved control flow analysis. Awesome work TS team!
Agreed! Nice work!
Great news, the improved type checking will definitely help make our company’s codebase more robust!
Too bad ES5 generators didn’t make it in 2.0, but I understand that the new transformation-based emitter needs some more work. We already have a workaround in place by transpiling to ES6 and piping through Babel to get ES5 generators. Looks like we’ll keep that extra Babel step in our build chain for just a bit longer.
Can someone explain this feature to me: “import text = require(“./hello.txt!text”);”?
I’m not that familiar with TS but why was this implemented in this way and not with an additional argument?
This is a common format for JS module loader to represent plugins. For instance requirejs, uses the the prefix to detonate the plugin name, so `text!./hello.txt` would be a request to load the file `./hello.txt` using the `text` loader plugin, which returns you the file contents as a string. similarly `json!./resource.json` returns you the result of calling `json.parse` on `./resource.json` as an object. you can find more details in: http://requirejs.org/docs/plugins.html
Great news! I’ve been anxious for TS 2.0 for months now.
Non-null types is *HUGE*! And is really a requirement for modern languages, IMO. It makes perfect sense in TypeScript, since nullability is really part of the type system.
Bummed about async/await delayed. But only until 2.1, which I’d imagine will still be released this year. Gut feeling is that async/await will make the largest impact on my codebases.
Great job, TS team and contributors.
2.0 is a HUGE release! Congrats, there is so much goodness: null checks, flow analysis, better lib management…
One question, you say:
“or just run
npm install -g typescript@beta”
Does it mean VS uses the global command-line TS when there is one, or is this intended for people not using VS?
For VS 2015 please use the standalone installer as per the link above. If you are using the commandline compiler through npm then use the npm install command.
How do I enable the strict null checks in Visual Studio? I’m not seeing a compiler option in the project property page.
I figured it out. It looks like we need to modify the .csproj to include the flag. I blogged how to do it here: http://debuggerdotbreak.judahgabriel.com/2016/07/11/enabling-typescript-2-0-strict-null-checks-in-a-visual-studio-project/
You have two options, the easiest is to add a tsconfig.json file to your project, if you do not have one already, and set
`”strictNullChecks”: true`. The other as noted in your blog is to set the MSBuild property `true` in your project. you can find more information about MSBuild propeorties in http://www.typescriptlang.org/docs/handbook/compiler-options-in-msbuild.html
I prefer to have tsconfig.json in my projects. By the way thank you for an update docs for MSBuild!
is there a download for the VS15 Preview?
No. TypeScript 2.0-beta will be published in box for the next preview of VS15.
Not excited at all. null-check and type analysis are barely usefull. Without async / await ES3/ES5 does not make sense to release any new version.
Strict null checks, readonly flags, discriminated unions, and specifying the type of “this” are all HUGE DEALS. Can’t wait for this release. Which, by the way, when is?
Guys, really well done.
On top of the non-nullable types, I also really like the glob support in tsconfig.json and “baseUrl” module support enhancement — thanks for those.
Non-nullable types are fantastic, it’ll make a big difference to our large code base. As will wildcards in module names.
Thanks team TypeScript!
Absolutely an amazing work!
The web will never be the same after TypeScript.
We can wait a little bit more for the async/await. For now, better encapsulation and non-nullables types are a great gift.
Improved control flow analysis is cool and useful. I’m not sure about the nullable types though. I’d preferred if you could declare it the other way round, e.g. let s: string not null; The way it is now, it can turn out hard to use the –strictNullChecks option in an existing code basis.
it is very great.
Great news!
Small question. There is this example in wiki, https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#example-2
Shouldn’t “b” in “let b = x && f(x);” be type of “number | string| undefined | null”, because it might be, 0, null, undefined, of string value from function?
As a matter of fact, we will consider amending this behavior in 2.1 when numeric literal types come in and we can express ‘0’ as a type.
Nice!
you guy amaze me!
It can NaN as well. BTW, are you going to distinguish between +0 and -0?
WTF! I was eagerly waiting for ES5 async/await. This is so disappointing 🙁
Can someone explain me, why is async/await so much desired ? Maybe I’m shortsighted and closed in my browser-side programming cage, but I can’t see it as enabler for some new continent of stunning possibilities. In fact I can imagine it only a bit simplifying AJAX requests…
Aysnc/await just cleans up a lot of asynchronous code instead of chaining callbacks or promises. It really boils down to cleaner syntax for the developer that reads more easily and IMO is easier to debug. You can target ES6 right now with typescript and see how they compile async/await into promises and generators, its pretty cool. This is a good example of the difference in syntax for the same behavior. AJAX is one example of an asynchronous process but there are more JS libraries taking advantage of Promises so I think this feature will become more important for the future of Javascript.
Just waiting for async/await. Not present, 🙁
why the null aware operator couldn’t have ? instead of !
the elvis operator is more obvious
@noor –
In C# for example the x?.y operator is the null conditional member access, and returns null if the left hand operand is null. This means the compiler introduces a null check for us in the code.
The new TypeScript x!.y operator seems to be slightly different – you are telling the compiler that you are sure x is not null, so just go ahead and make the call stifling the possible null compiler warning. The compiler is not introducing a null check for us.
Robert
It’s more like Apple Swift ! operator
WIN 10, VS /w update3, just installed TypeScript_Dev14full.
VS now highlighting “document.body” and “document.createElement” with red underline as if this properties does not exist on type Document.
In error list:
Error TS2339 Property ‘body’ does not exist on type ‘Document’.
Error TS2339 Property ‘createElement’ does not exist on type ‘Document’.
Error TS2339 Property ‘fillStyle’ does not exist on type ‘CanvasRenderingContext2D’.
Error TS2339 Property ‘fillRect’ does not exist on type ‘CanvasRenderingContext2D’.
…
Is it a bug, or should I install additional typings to fix this?
Deviating from the ES standard syntax-wise is a dangerous path. Maybe I can understand keywords like ‘readonly’ that are self-explanatory and have limited impact on the syntax, but the postfix operator crosses that line.
The whole argument for using TypeScript was that it built upon standard EcmaScript syntax. I can’t help but wonder what will happen when the postfix operator will be added to EcmaScript, but with a different meaning. How will TypeScript reconcile its special operator with the standard one?
Typescript is designed to be a super-set of the language, so it should be allowed and expected to *add* syntax when allowed. The postfix ! operator appears to just be a shorthand for type assertions which are already non-standard.
strs!.map(s => s.toLowerCase()); is the same as (strs as string[]).map(s => s.toLowerCase()) which is the same as (strs).map(s => s.toLowerCase()).
Actually, the ‘as’ syntax for type assertions is a good example of what happens when syntax collides. It was added to resolve the syntactic ambiguity between jsx and existing typescript syntax. I’d also hope that as typescript becomes more popular the ES standard process would take things like this into account when developing features.
Nice work guys! Non-nullables are huge for me. I encountered this exact problem, and now you provided a solution. Perfect.
===== PLEASE DO NOT DELETE COMMENTS!!!!!! =========
You may want to take a look at Scala.js (https://www.scala-js.org) which translates Scala to JavaScript (A safer way to build robust front-end web applications!). There is a comparison table which compares Scala.js against Typescript.
Look like demand for async (and disappointment by not implementing) is huge. So, if adding it is really few weeks away, as githubs states, then it will be wise to create intermediate version TS 2.05 which is 2.0 + async, than forcing devs for another months to wait, when rest of 2.1 features will be implemented, polished and tested.
TypeScript has nightly releases out of the master branch. Once the feature lands in the master branch, it will be available to every one to give it a try. We always love to get feedback for new features.
You can find more information about nightly releases and how to use them at: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Nightly%20Builds.md
I’ve been able to use async await with Typescript…
The key is to transpile Typescript to ES6 and then use Babel to go from ES6 to ES5. Sounds ugly but it’s not so bad; our webpack setup with awesome-typescript-loader actually makes it fairly easy due to webpack’s chainable loaders.
https://github.com/rangle/angular2-starter/blob/master/tsconfig.json
Aslo, non-nullable types FTW. I also like the new module feature; rehabilitating with legacy code just got a lot easier.
Webpack does help in that regard, but the performance is horrible. You have to parse each file 3 times (first pass = TS, second pass = Babel, third pass = Webpack) and because of loader abstraction there is no way to cache results between passes. Even with incremental compilation the performance degrades as you also need to generate source maps on each pass. It adds complexity to an already complicated build process and makes it harder to debug when something goes wrong either in the build process or with the generated code.
Perhaps – It hasn’t been problematic for me yet. That said, then the typescript compiler supports it natively I’ll happily switch. For now, slow but working is still better than not working 🙂
Of course the feature I really want in the short term is object spread 🙂
To all those complaining about the async/await delay, go take a look at https://github.com/Microsoft/TypeScript/pull/9175 and see some of the issues/discussions/blockers that are actually causing the delay. It’s taking time because they’re doing it properly.
Aw, that’s no fun! Can’t we carry on complaining bitterly about something completely awesome that we get entirely for free?
Good job guys! I was waiting for this for a while and I’m so damn excited to finally try it out.
Heads up: there appears to be a rather serious bug in TypeScript 2.0 beta for Visual Studio that prevents web apps from publishing.
The issue is described here: https://github.com/Microsoft/TypeScript/issues/9730
Unfortunately, this is a blocker for me, so in lieu of a workaround, I’ll be uninstalling TS 2.0 beta for VS.
Switch to WebStorm or IDEA.
Is there a way to restrict the strict null checks only to *my* code, so that library d.ts files are not affected?
Does this release add support for `npm install @types\package` to visual studio?
I upgraded to tsc 2.1.0-dev.20160919 in my linux / npm /webpack environment, and I’m getting a myriad of @type errors (core-js, webpack, node, etc), such as:
ERROR in [default] /home/username/node_modules/@types/core-js/index.d.ts:21:13
Duplicate identifier ‘PropertyKey’.
ERROR in [default] /home/username/node_modules/@types/node/index.d.ts:110:12
Subsequent variable declarations must have the same type. Variable ‘Buffer’ must be of type ‘{ new (str: string, encoding?: string): Buffer; new (size: number): Buffer; new (array: Uint8Arra…’, but here has type ‘{ new (str: string, encoding?: string): Buffer; new (size: number): Buffer; new (array: Uint8Arra…’.
Not even I’m barking up the right tree at this point.