In the four years since it went from an internal to a public open source, open design project, the combination of static type checking, transpiling and tooling in TypeScript has become something of a behind-the-scenes success, especially on large projects. You’d expect Microsoft projects like Visual Studio Code (and the Office Online apps) to be written in TypeScript, but so is Angular 2. Slack is currently migrating its Electron-based desktop app to TypeScript.
Many fundamental pieces in TypeScript 2.0 are also building blocks for features that will come in the next version TypeScript 2.1 (released into preview Wednesday), like using code flow analysis to better assign implicit types to variable and arrays. And with async/await set to become part of the next ECMAScript standard, TypeScript 2.1 will be able to transpile asynchronous code for a wider range of browsers.
Building on Node
The DefinitelyTyped site has more than 2,000 type declaration files and the TypeScript community created tools like TSD and Typing to pull type definitions from that and other repos, but Hejlsberg admits that’s become rather ‘messy.’
“We realized we needed to focus on making this a better experience, so for TypeScript we’re automatically scraping Definitely Typed and automatically packaging anything you put on there into node modules and putting those in a private namespace, @types. If you say ‘npm install jQuery’, you get the typing — it’s just a node module. Those node modules can have dependencies on other node modules, so we use the node dependency manager. You just install types now.”
He notes that frameworks like Angular ship with TypeScript types included so you get them automatically; “but if you don’t it’s just another npm install away, and that makes configuration a lot easier.”
Similarly, glob support was a popular request, so you can use wildcards in file paths in config files to include or exclude specific files, which gets very useful as projects get larger and need to pull source code from different locations. TypeScript couldn’t simply use the standard node module globbing support library, he explained.
“The way we’ve written TypeScript, it has very few dependencies. Often what happens with node projects is you have dependencies on this and on that and before you know it you’ve sucked down hundreds of node modules. We want TypeScript to be embeddable. If you want to run TypeScript in a browser, you can’t depend on node, so we had to write our own.”
Other new features are more fundamental, and let TypeScript adopt some of the programming ideas that developers are starting to become familiar with thanks to the success of functional languages like Swift and F#.
That, in turn, depends on control flow analysis. “Control flow analysis is about the compiler reasoning about what happening in your code. When you write an if statement …
‘if (x !== null)’,
… then you know x is not null inside there and if you return in there then you know x is not null in the remainder of the block you’re in. But it takes the compiler being to do code flow analysis to figure this out. It turns out non-nullability isn’t meaningful to do without code flow analysis.”
“With TypeScript and ECMAScript 2015 you can write OOP-style code with more each than before, but it’s also a very nice place to write functional style code,” he points out. (TypeScript itself is written entirely in functional style code with no classes at all).
“The functional way of handling those requests is more that you describe the various request shapes using object type declarations that each have a discriminant property. For example you may have a ‘kind’ property that in one declaration has the literal type ‘get,’ in another has the literal type ‘update,’ and in a third has the literal type ‘delete.’ You then say that a request can be any one of those objects by declaring a union type with each of the possibilities. So now you’ve described, in a closed world way, all the things that are possible and you’ve described the discriminants.”
“We’re Just formalizing patterns that are commonly in use, but this allows you to have the compiler validate that you handled all the possible requests and you didn’t access properties off this request that actually belong to a different type of request,” he said.