{"id":1917,"date":"2018-10-08T23:21:42","date_gmt":"2018-10-09T06:21:42","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=1917"},"modified":"2019-02-27T22:30:38","modified_gmt":"2019-02-28T06:30:38","slug":"announcing-typescript-3-1-rc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-3-1-rc\/","title":{"rendered":"Announcing TypeScript 3.1 RC"},"content":{"rendered":"<div style=\"font-size: 16px;\">Today we&#8217;re happy to announce the availability of the release candidate (RC) of TypeScript 3.1. Our intent with the RC is to gather any and all feedback so that we can ensure our final release is as pleasant as possible.If you&#8217;d like to give it a shot now, you can get the RC <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild\" rel=\"nofollow\">through NuGet<\/a>, or use npm with the following command:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>npm install -g typescript@rc<\/pre>\n<\/div>\n<p>You can also get editor support by<\/p>\n<ul>\n<li><a href=\"http:\/\/download.microsoft.com\/download\/7\/0\/A\/70A6AC0E-8934-4396-A43E-445059F430EA\/3.1.0-TS-release-dev14update3-20180911.1\/TypeScript_SDK.exe\" rel=\"nofollow\">Downloading for Visual Studio 2017<\/a> (for version 15.2 or later)<\/li>\n<li><a href=\"http:\/\/download.microsoft.com\/download\/6\/D\/8\/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA\/3.1.0-TS-release-dev14update3-20180911.1\/TypeScript_Dev14Full.exe\" rel=\"nofollow\">Downloading for Visual Studio 2015<\/a> (with <a href=\"https:\/\/www.visualstudio.com\/en-us\/news\/releasenotes\/vs2015-update3-vs\" rel=\"nofollow\">Update 3<\/a>)<\/li>\n<li>Following directions for <a href=\"https:\/\/code.visualstudio.com\/Docs\/languages\/typescript#_using-newer-typescript-versions\" rel=\"nofollow\">Visual Studio Code<\/a> and <a href=\"https:\/\/github.com\/Microsoft\/TypeScript-Sublime-Plugin\/#note-using-different-versions-of-typescript\">Sublime Text<\/a>.<\/li>\n<\/ul>\n<p>Let&#8217;s look at what&#8217;s coming in TypeScript 3.1!<\/p>\n<h2><a id=\"user-content-mappable-tuple-and-array-types\" class=\"anchor\" href=\"https:\/\/gist.github.com\/DanielRosenwasser\/554b6b95e65c4dde526f2bcb2ee9129b#mappable-tuple-and-array-types\"><\/a>Mappable tuple and array types<\/h2>\n<p>Mapping over values in a list is one of the most common patterns in programming. As an example, let&#8217;s take a look at the following JavaScript code:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">function stringifyAll(...elements) {\r\n    return elements.map(x =&gt; String(x));\r\n}<\/pre>\n<\/div>\n<p>The <code style=\"color: #a31515;\"><\/code>stringifyAll function takes any number of values, converts each element to a string, places each result in a new array, and returns that array. If we want to have the most general type for <code style=\"color: #a31515;\"><\/code>stringifyAll, we&#8217;d declare it as so:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">declare function stringifyAll(...elements: unknown[]): Array&lt;string&gt;;<\/pre>\n<\/div>\n<p>That basically says, &#8220;this thing takes any number of elements, and returns an array of <code style=\"color: #a31515;\"><\/code>strings&#8221;; however, we&#8217;ve lost a bit of information about <code style=\"color: #a31515;\"><\/code>elements in that transformation.<\/p>\n<p>Specifically, the type system doesn&#8217;t remember the number of elements user passed in, so our output type doesn&#8217;t have a known length either. We can do something like that with overloads:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true \">declare function stringifyAll(...elements: []): string[];\r\ndeclare function stringifyAll(...elements: [unknown]): [string];\r\ndeclare function stringifyAll(...elements: [unknown, unknown]): [string, string];\r\ndeclare function stringifyAll(...elements: [unknown, unknown, unknown]): [string, string, string];\r\n\/\/ ... etc<\/pre>\n<p><em>Ugh<\/em>. And we didn&#8217;t even cover taking <em>four<\/em> elements yet. You end up special-casing all of these possible overloads, and you end up with what we like to call the &#8220;death by a thousand overloads&#8221; problem. Sure, we could use conditional types instead of overloads, but then you&#8217;d have a bunch of nested conditional types.<\/p>\n<\/div>\n<p><em>If only<\/em> there was a way to uniformly map over each of the types here&#8230;<\/p>\n<p>Well, TypeScript already has something that sort of does that. TypeScript has a concept called a mapped object type which can generate new types out of existing ones. For example, given the following <code style=\"color: #a31515;\"><\/code>Person type,<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">interface Person {\r\n    name: string;\r\n    age: number;\r\n    isHappy: boolean;\r\n}<\/pre>\n<\/div>\n<p>we might want to convert each property to a string as above:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">interface StringyPerson {\r\n    name: string;\r\n    age: string;\r\n    isHappy: string;\r\n}\r\n\r\nfunction stringifyPerson(p: Person) {\r\n    const result = {} as StringyPerson;\r\n    for (const prop in p) {\r\n        result[prop] = String(p[prop]);\r\n    }\r\n    return result;\r\n}<\/pre>\n<\/div>\n<p>Though notice that <code style=\"color: #a31515;\"><\/code>stringifyPerson is pretty general. We can abstract the idea of <code style=\"color: #a31515;\"><\/code>Stringify-ing types using a mapped object type over the properties of any given type:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">type Stringify&lt;T&gt; = {\r\n    [K in keyof T]: string\r\n};<\/pre>\n<\/div>\n<p>For those unfamiliar, we read this as &#8220;for every property named <code style=\"color: #a31515;\"><\/code>K in <code style=\"color: #a31515;\"><\/code>T, produce a new property of that name with the type <code style=\"color: #a31515;\"><\/code>string.<\/p>\n<p>and rewrite our function to use that:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">function stringifyProps&lt;T&gt;(p: T) {\r\n    const result = {} as Stringify&lt;T&gt;;\r\n    for (const prop in p) {\r\n        result[prop] = String(p[prop]);\r\n    }\r\n    return result;\r\n}\r\n\r\nstringifyProps({ hello: 100, world: true }); \/\/ has type `{ hello: string, world: string }`<\/pre>\n<\/div>\n<p>Seems like we have what we want! However, if we tried changing the type of <code style=\"color: #a31515;\"><\/code>stringifyAll to return a <code style=\"color: #a31515;\"><\/code>Stringify:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">declare function stringifyAll&lt;T extends unknown[]&gt;(...elements: T): Stringify&lt;T&gt;;<\/pre>\n<\/div>\n<p>And then tried calling it on an array or tuple, we&#8217;d only get something that&#8217;s <em>almost<\/em> useful prior to TypeScript 3.1. Let&#8217;s give it a shot on an older version of TypeScript like 3.0:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">let stringyCoordinates = stringifyAll(100, true);\r\n\r\n\/\/ No errors!\r\nlet first: string = stringyCoordinates[0];\r\nlet second: string = stringyCoordinates[1];<\/pre>\n<\/div>\n<p>Looks like our tuple indexes have been mapped correctly! Let&#8217;s check the grab the length now and make sure that&#8217;s right:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">   let len: 2 = stringyCoordinates.length\r\n\/\/     ~~~\r\n\/\/ Type 'string' is not assignable to type '2'.<\/pre>\n<\/div>\n<p>Uh. <code style=\"color: #a31515;\"><\/code>string? Well, let&#8217;s try to iterate on our coordinates.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"> stringyCoordinates.forEach(x =&gt; console.log(x));\r\n\/\/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\/\/ Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.<\/pre>\n<\/div>\n<p>Huh? What&#8217;s causing this gross error message? Well our <code style=\"color: #a31515;\"><\/code>Stringify mapped type not only mapped our tuple members, it also mapped over the methods of <code style=\"color: #a31515;\"><\/code>Array, as well as the <code style=\"color: #a31515;\"><\/code>length property! So <code style=\"color: #a31515;\"><\/code>forEach and <code style=\"color: #a31515;\"><\/code>length both have the type <code style=\"color: #a31515;\"><\/code>string!<\/p>\n<p>While technically consistent in behavior, the majority of our team felt that this use-case should just work. Rather than introduce a new concept for mapping over a tuple, mapped object types now just &#8220;do the right thing&#8221; when iterating over tuples and arrays. This means that if you&#8217;re already using existing mapped types like <code style=\"color: #a31515;\"><\/code>Partial or <code style=\"color: #a31515;\"><\/code>Required from <code style=\"color: #a31515;\"><\/code>lib.d.ts, they automatically work on tuples and arrays now.<\/p>\n<h2><a id=\"user-content-properties-on-function-declarations\" class=\"anchor\" href=\"https:\/\/gist.github.com\/DanielRosenwasser\/554b6b95e65c4dde526f2bcb2ee9129b#properties-on-function-declarations\"><\/a>Properties on function declarations<\/h2>\n<p>In JavaScript, functions are just objects. This means we can tack properties onto them as we please:<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\">export function readFile(path) {\r\n    \/\/ ...\r\n}\r\n\r\nreadFile.async = function (path, callback) {\r\n    \/\/ ...\r\n}<\/pre>\n<\/div>\n<p>TypeScript&#8217;s traditional approach to this has been an extremely versatile construct called <code style=\"color: #a31515;\"><\/code>namespaces (a.k.a. &#8220;internal modules&#8221; if you&#8217;re old enough to remember). In addition to organizing code, namespaces support the concept of <em>value-merging<\/em>, where you can add properties to classes and functions in a declarative way:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">export function readFile() {\r\n    \/\/ ...\r\n}\r\n\r\nexport namespace readFile {\r\n    export function async() {\r\n        \/\/ ...\r\n    }\r\n}<\/pre>\n<\/div>\n<p>While perhaps elegant for their time, the construct hasn&#8217;t aged well. ECMAScript modules have become the preferred format for organizing new code in the broader TypeScript &amp; JavaScript community, and namespaces are TypeScript-specific. Additionally, namespaces don&#8217;t merge with <code style=\"color: #a31515;\"><\/code>var, <code style=\"color: #a31515;\"><\/code>let, or <code style=\"color: #a31515;\"><\/code>const declarations, so code like the following (which is motivated by <code style=\"color: #a31515;\"><\/code>defaultProps from React):<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">export const FooComponent =&gt; ({ name }) =&gt; (\r\n    &lt;div&gt;Hello! I am {name}&lt;\/div&gt;\r\n);\r\n\r\nFooComponent.defaultProps = {\r\n    name: \"(anonymous)\",\r\n};<\/pre>\n<\/div>\n<p>can&#8217;t even simply be converted to<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">export const FooComponent =&gt; ({ name }) =&gt; (\r\n    &lt;div&gt;Hello! I am {name}&lt;\/div&gt;\r\n);\r\n\r\n\/\/ Doesn't work!\r\nnamespace FooComponent {\r\n    export const defaultProps = {\r\n        name: \"(anonymous)\",\r\n    };\r\n}<\/pre>\n<\/div>\n<p>All of this collectively can be frustrating since it makes migrating to TypeScript harder.<\/p>\n<p>Given all of this, we felt that it would be better to make TypeScript a bit &#8220;smarter&#8221; about these sorts of patterns. In TypeScript 3.1, for any function declaration or <code style=\"color: #a31515;\"><\/code>const declaration that&#8217;s initialized with a function, the type-checker will analyze the containing scope to track any added properties. That means that both of the examples &#8211; both our <code style=\"color: #a31515;\"><\/code>readFile as well as our <code style=\"color: #a31515;\"><\/code>FooComponent examples &#8211; work without modification in TypeScript 3.1!<\/p>\n<p>As an added bonus, this functionality in conjunction with TypeScript 3.0&#8217;s support for <code style=\"color: #a31515;\"><\/code>JSX.LibraryManagedAttributes makes migrating an untyped React codebase to TypeScript <em>significantly<\/em> easier, since it understands which attributes are optional in the presence of <code style=\"color: #a31515;\"><\/code>defaultProps:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\">\/\/ TypeScript understands that both are valid:\r\n&lt;FooComponent \/&gt;\r\n&lt;FooComponent name=\"Nathan\" \/&gt;<\/pre>\n<\/div>\n<h2><a id=\"user-content-breaking-changes\" class=\"anchor\" href=\"https:\/\/gist.github.com\/DanielRosenwasser\/554b6b95e65c4dde526f2bcb2ee9129b#breaking-changes\"><\/a>Breaking Changes<\/h2>\n<p>Our team always strives to avoid introducing breaking changes, but unfortunately there are some to be aware of for TypeScript 3.1.<\/p>\n<h3><a id=\"user-content-vendor-specific-declarations-removed\" class=\"anchor\" href=\"https:\/\/gist.github.com\/DanielRosenwasser\/554b6b95e65c4dde526f2bcb2ee9129b#vendor-specific-declarations-removed\"><\/a>Vendor-specific declarations removed<\/h3>\n<p>TypeScript 3.1 now generates parts of <code style=\"color: #a31515;\"><\/code>lib.d.ts (and other built-in declaration file libraries) using Web IDL files provided from the WHATWG DOM specification. While this means that <code style=\"color: #a31515;\"><\/code>lib.d.ts will be easier to keep up-to-date, many vendor-specific types have been removed. We&#8217;ve covered this in more detail <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Breaking-Changes\">on our wiki<\/a>.<\/p>\n<h3><a id=\"user-content-differences-in-narrowing-functions\" class=\"anchor\" href=\"https:\/\/gist.github.com\/DanielRosenwasser\/554b6b95e65c4dde526f2bcb2ee9129b#differences-in-narrowing-functions\"><\/a>Differences in narrowing functions<\/h3>\n<p>Using the <code style=\"color: #a31515;\"><\/code>typeof foo === &#8220;function&#8221; type guard may provide different results when intersecting with relatively questionable union types composed of <code style=\"color: #a31515;\"><\/code>{}, <code style=\"color: #a31515;\"><\/code>Object, or unconstrained generics.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true  \">function foo(x: unknown | (() =&gt; string)) {\r\n    if (typeof x === \"function\") {\r\n        let a = x()\r\n    }\r\n}<\/pre>\n<\/div>\n<p>You can read more on <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Breaking-Changes#narrowing-functions-now-intersects--object-and-unconstrained-generic-type-parameters\">the breaking changes section of our wiki<\/a>.<\/p>\n<h2><a id=\"user-content-going-forward\" class=\"anchor\" href=\"https:\/\/gist.github.com\/DanielRosenwasser\/554b6b95e65c4dde526f2bcb2ee9129b#going-forward\"><\/a>Going forward<\/h2>\n<p>We&#8217;re looking forward to hearing about your experience with the RC. As always, keep an eye on <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">our roadmap<\/a> to get the whole picture of the release as we stabilize. We expect to ship our final release in just a few weeks, so give it a shot now!<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re happy to announce the availability of the release candidate (RC) of TypeScript 3.1. Our intent with the RC is to gather any and all feedback so that we can ensure our final release is as pleasant as possible.If you&#8217;d like to give it a shot now, you can get the RC through NuGet, [&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-1917","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 the release candidate (RC) of TypeScript 3.1. Our intent with the RC is to gather any and all feedback so that we can ensure our final release is as pleasant as possible.If you&#8217;d like to give it a shot now, you can get the RC through NuGet, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1917","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=1917"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1917\/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=1917"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=1917"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=1917"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}