{"id":1925,"date":"2019-01-31T20:29:48","date_gmt":"2019-01-31T20:29:48","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/typescript\/?p=1925"},"modified":"2019-02-27T20:42:23","modified_gmt":"2019-02-28T04:42:23","slug":"announcing-typescript-3-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-3-3\/","title":{"rendered":"Announcing TypeScript 3.3"},"content":{"rendered":"<div style=\"font-size: 16px;\">\n<p>Today we&#8217;re happy to announce the availability of TypeScript 3.3!If you&#8217;re unfamiliar with TypeScript, it&#8217;s a language that brings static type-checking to JavaScript so that you can catch issues before you even run your code &#8211; or before you even save your file. It also includes the latest JavaScript features from the ECMAScript standard on older browsers and runtimes by compiling those features into a form that they understand. But beyond type-checking and compiling your code, TypeScript also provides tooling in your favorite editor so that you can jump to the definition of any variable, find who&#8217;s using a given function, and automate refactorings and fixes to common problems.<\/p>\n<p>TypeScript even provides this for JavaScript users (and can also type-check JavaScript code typed with JSDoc), so if you&#8217;ve used editors like Visual Studio or Visual Studio Code on a <code style=\"color: #a31515;\">.js<\/code> file, TypeScript is powering that experience.<\/p>\n<p>To get started with TypeScript, you can get it <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild\" rel=\"nofollow\">through NuGet<\/a>, or through npm with the following command:<\/p>\n<pre class=\"lang:default decode:true \">npm install -g typescript<\/pre>\n<p>You can also get editor support by<\/p>\n<ul>\n<li><a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=TypeScriptTeam.typescript-331-vs2017\">Downloading for Visual Studio 2017<\/a> (for version 15.2 or later)<\/li>\n<li>Using tonight&#8217;s <a href=\"https:\/\/code.visualstudio.com\/insiders\/\" rel=\"nofollow\">Visual Studio Code Insiders<\/a> (or <a href=\"https:\/\/code.visualstudio.com\/Docs\/languages\/typescript#_using-newer-typescript-versions\" rel=\"nofollow\">by manually setting the editor up<\/a>).<\/li>\n<li><a href=\"https:\/\/packagecontrol.io\/packages\/TypeScript\" rel=\"nofollow\">Sublime Text 3 via PackageControl<\/a>.<\/li>\n<\/ul>\n<p>TypeScript 3.3 is a smaller release than usual and contains no breaking changes, so it should be easy to upgrade if you&#8217;re on an older version. Let&#8217;s explore what&#8217;s new in 3.3!<\/p>\n<h2>Improved behavior for calling union types<\/h2>\n<p>When TypeScript has a union type <code style=\"color: #a31515;\">A | B<\/code>, it allows you to access all the properties common to both <code style=\"color: #a31515;\">A<\/code> and <code style=\"color: #a31515;\">B<\/code> (i.e. the intersection of members).<\/p>\n<pre class=\"lang:default decode:true \">interface A {\r\n    aProp: string;\r\n    commonProp: string;\r\n}\r\n\r\ninterface B {\r\n    bProp: number;\r\n    commonProp: number\r\n}\r\n\r\ntype Union = A | B;\r\n\r\ndeclare let x: Union;\r\n\r\nx.aProp; \/\/ error - 'B' doesn't have the property 'aProp'\r\nx.bProp; \/\/ error - 'A' doesn't have the property 'bProp'\r\nx.commonProp; \/\/ okay! Both 'A' and 'B' have a property named `commonProp`.<\/pre>\n<p>This behavior should feel intuitive &#8211; you can only get a property off of a union type if it&#8217;s known to be in every type of the union.<\/p>\n<p>What about, instead of accessing properties, we&#8217;re dealing with calling types? Well, when <em>every<\/em> type has exactly one signature with identical parameters, things just work and you can call these types.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:js decode:true \">type CallableA = (x: boolean) =&gt; string;\r\ntype CallableB = (x: boolean) =&gt; number;\r\n\r\ntype CallableUnion = CallableA | CallableB;\r\n\r\ndeclare let f: CallableUnion;\r\n\r\nlet x = f(true); \/\/ Okay! Returns a 'string | number'.<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>However, this restriction was sometimes, well, <em>overly<\/em> restrictive.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true \">type Fruit = \"apple\" | \"orange\";\r\ntype Color = \"red\" | \"orange\";\r\n\r\ntype FruitEater = (fruit: Fruit) =&gt; number;     \/\/ eats and ranks the fruit\r\ntype ColorConsumer = (color: Color) =&gt; string;  \/\/ consumes and describes the colors\r\n\r\ndeclare let f: FruitEater | ColorConsumer;\r\n\r\n\/\/ Cannot invoke an expression whose type lacks a call signature.\r\n\/\/   Type 'FruitEater | ColorConsumer' has no compatible call signatures.ts(2349)\r\nf(\"orange\");<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Silly example and poor error message aside, both <code style=\"color: #a31515;\">FruitEater<\/code>s and <code style=\"color: #a31515;\">ColorConsumer<\/code>s should be able to take the string <code style=\"color: #a31515;\">\"orange\"<\/code>, and return either a <code style=\"color: #a31515;\">number<\/code> or a <code style=\"color: #a31515;\">string<\/code>.<\/p>\n<p>In TypeScript 3.3, this is no longer an error.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true \">type Fruit = \"apple\" | \"orange\";\r\ntype Color = \"red\" | \"orange\";\r\n\r\ntype FruitEater = (fruit: Fruit) =&gt; number;     \/\/ eats and ranks the fruit\r\ntype ColorConsumer = (color: Color) =&gt; string;  \/\/ consumes and describes the colors\r\n\r\ndeclare let f: FruitEater | ColorConsumer;\r\n\r\nf(\"orange\"); \/\/ It works! Returns a 'number | string'.\r\n\r\nf(\"apple\");  \/\/ error - Argument of type '\"apple\"' is not assignable to parameter of type '\"orange\"'.\r\n\r\nf(\"red\");    \/\/ error - Argument of type '\"red\"' is not assignable to parameter of type '\"orange\"'.<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>In TypeScript 3.3, the parameters of these signatures are <em>intersected<\/em> together to create a new signature. In the example above, the parameters <code style=\"color: #a31515;\">fruit<\/code> and <code style=\"color: #a31515;\">color<\/code> are intersected together to a new parameter of type <code style=\"color: #a31515;\">Fruit &amp; Color<\/code>. <code style=\"color: #a31515;\">Fruit &amp; Color<\/code> is really the same as <code style=\"color: #a31515;\">(\"apple\" | \"orange\") &amp; (\"red\" | \"orange\")<\/code> which is equivalent to <code style=\"color: #a31515;\">(\"apple\" &amp; \"red\") | (\"apple\" &amp; \"orange\") | (\"orange\" &amp; \"red\") | (\"orange\" &amp; \"orange\")<\/code>. Each of those impossible intersections evaporates, and we&#8217;re left with <code style=\"color: #a31515;\">\"orange\" &amp; \"orange\"<\/code> which is just <code style=\"color: #a31515;\">\"orange\"<\/code>.<\/p>\n<p>There are still some restrictions though. This new behavior only kicks in when at most one type in the union has multiple overloads, and at most one type in the union has a generic signature. That means methods on <code style=\"color: #a31515;\">number[] | string[]<\/code> like <code style=\"color: #a31515;\">map<\/code> (which is generic) still won&#8217;t be callable.<\/p>\n<p>On the other hand, methods like <code style=\"color: #a31515;\">forEach<\/code> will now be callable, but under <code style=\"color: #a31515;\">noImplicitAny<\/code> there may be some issues.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true \">interface Dog {\r\n    kind: \"pupper\"\r\n    dogProp: any;\r\n}\r\ninterface Cat {\r\n    kind: \"kittyface\"\r\n    catProp: any;\r\n}\r\n\r\nconst catOrDogArray: Dog[] | Cat[] = [];\r\n\r\ncatOrDogArray.forEach(animal =&gt; {\r\n    \/\/                ~~~~~~ error!\r\n    \/\/ Parameter 'animal' implicitly has an 'any' type.<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"\">});<\/pre>\n<\/div>\n<p>While we&#8217;ll continue to improve the experience here, this is strictly more capable in TypeScript 3.3, and adding an explicit type annotation will work.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true \">interface Dog {\r\n    kind: \"pupper\"\r\n    dogProp: any;\r\n}\r\ninterface Cat {\r\n    kind: \"kittyface\"\r\n    catProp: any;\r\n}\r\n\r\nconst catOrDogArray: Dog[] | Cat[] = [];\r\ncatOrDogArray.forEach((animal: Dog | Cat) =&gt; {\r\n    if (animal.kind === \"pupper\") {\r\n        animal.dogProp;\r\n        \/\/ ...\r\n    }\r\n    else if (animal.kind === \"kittyface\") {\r\n        animal.catProp;\r\n        \/\/ ...\r\n    }\r\n});<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Incremental file watching for composite projects in <code style=\"color: #a31515; font-size: 29px;\">--build --watch<\/code><\/h2>\n<p>In TypeScript 3.0, we introduced a new feature for structuring builds called &#8220;composite projects&#8221;. Part of the goal here was to ensure users could break up large projects into smaller parts that build quickly and preserve project structure, without compromising the existing TypeScript experience. Thanks to composite projects, TypeScript can use <code style=\"color: #a31515;\">--build<\/code> mode to recompile only the set of projects and dependencies. You can think of this as optimizing <em>inter<\/em>-project builds.<\/p>\n<p>However, around last year our team also shipped optimized <code style=\"color: #a31515;\">--watch<\/code> mode builds via a new incremental &#8220;builder&#8221; API. In a similar vein, the entire idea is that this mode only re-checks and re-emits changed files or files whose dependencies might impact type-checking. You can think of this as optimizing <em>intra<\/em>-project builds.<\/p>\n<p>Perhaps ironically, building composite projects using <code style=\"color: #a31515;\">--build --watch<\/code> actually didn&#8217;t use this infrastructure. An update in one project under <code style=\"color: #a31515;\">--build --watch<\/code> mode would force a full build of that project, rather than determining which files within that project were affected.<\/p>\n<p>In TypeScript 3.3, <code style=\"color: #a31515;\">--build<\/code> mode&#8217;s <code style=\"color: #a31515;\">--watch<\/code> flag <em>does<\/em> leverage incremental file watching as well. That can mean signficantly faster builds under <code style=\"color: #a31515;\">--build --watch<\/code>. In our testing, this functionality has resulted in <strong>a reduction of 50% to 75% in build times<\/strong> of the original <code style=\"color: #a31515;\">--build --watch<\/code> times. <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/29161\">You can read more on the original pull request for the change<\/a> to see specific numbers, but we believe most composite project users will see significant wins here.<\/p>\n<h2>JavaScript editing in Sublime Text<\/h2>\n<p>Thanks to work done by former TypeScript team member <a href=\"https:\/\/github.com\/zhengbli\">Zhengbo Li<\/a> and community contributor <a href=\"https:\/\/github.com\/idiotWu\">@idiotWu<\/a>, our TypeScript plugin for Sublime Text now supports editing in JavaScript files! This means users will get more accurate completions, rename, go-to-definition, and more in JavaScript code that utilizes JSDoc and interoperates with TypeScript code.<\/p>\n<p><img decoding=\"async\" style=\"max-height: 600px;\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2019\/01\/js-in-sublime-3.3.gif\" alt=\"Using JavaScript editing features in a .js file in Sublime Text 3\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>In case you missed it, the TypeScript project recently published <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/issues\/29288\">our 6-month roadmap<\/a> to outline the work we expect to tackle between January and June. To keep track of upcoming features in TypeScript 3.4 and forward, you can keep an eye on <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">our feature roadmap page<\/a>.<\/p>\n<p>We hope that TypeScript 3.3 continues to make you more productive, and makes you happier as you code. If you&#8217;re enjoying it, let us know <a href=\"https:\/\/twitter.com\/typescriptlang\" rel=\"nofollow\">on Twitter<\/a>, and if you&#8217;ve got any suggestions on what we can improve, <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/issues\/new\/choose\">file an issue on GitHub<\/a>.<\/p>\n<p>Happy hacking!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript team<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re happy to announce the availability of TypeScript 3.3!If you&#8217;re unfamiliar with TypeScript, it&#8217;s a language that brings static type-checking to JavaScript so that you can catch issues before you even run your code &#8211; or before you even save your file. It also includes the latest JavaScript features from the ECMAScript standard on [&hellip;]<\/p>\n","protected":false},"author":381,"featured_media":1797,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1925","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Today we&#8217;re happy to announce the availability of TypeScript 3.3!If you&#8217;re unfamiliar with TypeScript, it&#8217;s a language that brings static type-checking to JavaScript so that you can catch issues before you even run your code &#8211; or before you even save your file. It also includes the latest JavaScript features from the ECMAScript standard on [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/users\/381"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/comments?post=1925"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1925\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media\/1797"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media?parent=1925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=1925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=1925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}