{"id":2161,"date":"2019-03-15T14:27:15","date_gmt":"2019-03-15T22:27:15","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=2161"},"modified":"2019-03-15T17:01:38","modified_gmt":"2019-03-16T01:01:38","slug":"announcing-typescript-3-4-rc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-3-4-rc\/","title":{"rendered":"Announcing TypeScript 3.4 RC"},"content":{"rendered":"<p>Today we&#8217;re happy to announce the availability of our release candidate (RC) of TypeScript 3.4. Our hope is to collect feedback and early issues to ensure our final release is simple to pick up and use right away.<\/p>\n<p>To get started using the RC, you can get it <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 class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\">npm install -g typescript@rc<\/pre>\n<\/div>\n<p>You can also get editor support by<\/p>\n<ul>\n<li><a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=TypeScriptTeam.TypeScript-340rc-vs2017\" rel=\"nofollow\">Downloading for Visual Studio 2017<\/a> (for version 15.2 or later)<\/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 explore what&#8217;s new in 3.4!<\/p>\n<h2><\/h2>\n<h2>Faster subsequent builds with the <code>--incremental<\/code> flag<\/h2>\n<p>Because TypeScript files are compiled, it introduces an intermediate step between writing and running your code. One of our goals is to minimize built time given any change to your program. One way to do that is by running TypeScript in <code>--watch<\/code> mode. When a file changes under <code>--watch<\/code> mode, TypeScript is able to use your project&#8217;s previously-constructed dependency graph to determine which files could potentially have been affected and need to be re-checked and potentially re-emitted. This can avoid a full type-check and re-emit which can be costly.<\/p>\n<p>But it&#8217;s unrealistic to expect <em>all<\/em> users to keep a <code>tsc --watch<\/code> process running overnight just to have faster builds tomorrow morning. What about cold builds? Over the past few months, we&#8217;ve been working to see if there&#8217;s a way to save the appropriate information from <code>--watch<\/code> mode to a file and use it from build to build.<\/p>\n<p>TypeScript 3.4 introduces a new flag called <code>--incremental<\/code> which tells TypeScript to save information about the project graph from the last compilation. The next time TypeScript is invoked with <code>--incremental<\/code>, it will use that information to detect the least costly way to type-check and emit changes to your project.<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ tsconfig.json<\/span>\r\n{\r\n    <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>compilerOptions<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> {\r\n        <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>incremental<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">true<\/span>,\r\n        <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>outDir<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/lib<span class=\"pl-pds\">\"<\/span><\/span>\r\n    },\r\n    <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>include<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> [<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/src<span class=\"pl-pds\">\"<\/span><\/span>]\r\n}<\/pre>\n<\/div>\n<p>By default with these settings, when we run <code>tsc<\/code>, TypeScript will look for a file called <code>.tsbuildinfo<\/code> in our output directory (<code>.\/lib<\/code>). If <code>.\/lib\/.tsbuildinfo<\/code> doesn&#8217;t exist, it&#8217;ll be generated. But if it does, <code>tsc<\/code> will try to use that file to incrementally type-check and update our output files.<\/p>\n<p>These <code>.tsbuildinfo<\/code> files can be safely deleted and don&#8217;t have any impact on our code at runtime &#8211; they&#8217;re purely used to make compilations faster. We can also name them anything that we want, and place them anywhere we want using the <code>--tsBuildInfoFile<\/code> flag.<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ front-end.tsconfig.json<\/span>\r\n{\r\n    <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>compilerOptions<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> {\r\n        <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>incremental<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">true<\/span>,\r\n        <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>tsBuildInfoFile<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/buildcache\/front-end<span class=\"pl-pds\">\"<\/span><\/span>,\r\n        <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>outDir<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/lib<span class=\"pl-pds\">\"<\/span><\/span>\r\n    },\r\n    <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>include<span class=\"pl-pds\">\"<\/span><\/span><span class=\"pl-k\">:<\/span> [<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/src<span class=\"pl-pds\">\"<\/span><\/span>]\r\n}<\/pre>\n<\/div>\n<p>As long as nobody else tries writing to the same cache file, we should be able to enjoy faster incremental cold builds.<\/p>\n<h3><\/h3>\n<h3>Composite projects<\/h3>\n<p>Part of the intent with composite projects (<code>tsconfig.json<\/code>s with <code>composite<\/code> set to <code>true<\/code>) is that references between different projects can be built incrementally. As such, composite projects will <strong>always<\/strong> produce <code>.tsbuildinfo<\/code> files.<\/p>\n<h3><\/h3>\n<h3><code>outFile<\/code><\/h3>\n<p>When <code>outFile<\/code> is used, the build information file&#8217;s name will be based on the output file&#8217;s name. As an example, if our output JavaScript file is <code>.\/output\/foo.js<\/code>, then under the <code>--incremental<\/code> flag, TypeScript will generate the file <code>.\/output\/foo.tsbuildinfo<\/code>. As above, this can be controlled with the <code>--tsBuildInfoFile<\/code> flag.<\/p>\n<h3><\/h3>\n<h3>The <code>--incremental<\/code> file format and versioning<\/h3>\n<p>While the file generated by <code>--incremental<\/code> is JSON, the file isn&#8217;t mean to be consumed by any other tool. We can&#8217;t provide any guarantees of stability for its contents, and in fact, our current policy is that any one version of TypeScript will not understand <code>.tsbuildinfo<\/code> files generated from another version.<\/p>\n<h2><\/h2>\n<h2>Improvements for <code>ReadonlyArray<\/code> and <code>readonly<\/code> tuples<\/h2>\n<p>TypeScript 3.4 makes it a little bit easier to use read-only array-like types.<\/p>\n<h3><\/h3>\n<h3>A new syntax for <code>ReadonlyArray<\/code><\/h3>\n<p>The <code>ReadonlyArray<\/code> type describes <code>Array<\/code>s that can only be read from. Any variable with a handle to a <code>ReadonlyArray<\/code> can&#8217;t add, remove, or replace any elements of the array.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> foo(<span class=\"pl-v\">arr<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">ReadonlyArray<\/span>&lt;<span style=\"color: #0000ff;\">string<\/span>&gt;) {\r\n    <span class=\"pl-smi\">arr<\/span>.<span class=\"pl-c1\">slice<\/span>();        <span style=\"color: #148A14;\">\/\/ okay<\/span>\r\n    <span class=\"pl-smi\">arr<\/span>.<span class=\"pl-c1\">push<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello!<span class=\"pl-pds\">\"<\/span><\/span>); <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n}<\/pre>\n<\/div>\n<p>While it&#8217;s often good practice to use <code>ReadonlyArray<\/code> over <code>Array<\/code> for the purpose of intent, it&#8217;s often been a pain given that arrays have a nicer syntax. Specifically, <code>number[]<\/code> is a shorthand version of <code>Array&lt;number&gt;<\/code>, just as <code>Date[]<\/code> is a shorthand for <code>Array&lt;Date&gt;<\/code>.<\/p>\n<p>TypeScript 3.4 introduces a new syntax for <code>ReadonlyArray<\/code> using a new <code>readonly<\/code> modifier for array types.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> foo(<span class=\"pl-v\">arr<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #0000ff;\">string<\/span>[]) {\r\n    <span class=\"pl-smi\">arr<\/span>.<span class=\"pl-c1\">slice<\/span>();        <span style=\"color: #148A14;\">\/\/ okay<\/span>\r\n    <span class=\"pl-smi\">arr<\/span>.<span class=\"pl-c1\">push<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello!<span class=\"pl-pds\">\"<\/span><\/span>); <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n}<\/pre>\n<\/div>\n<h3><\/h3>\n<h3><code>readonly<\/code> tuples<\/h3>\n<p>TypeScript 3.4 also introduces new support for <code>readonly<\/code> tuples. We can prefix any tuple type with the <code>readonly<\/code> keyword to make it a <code>readonly<\/code> tuple, much like we now can with array shorthand syntax. As you might expect, unlike ordinary tuples whose slots could be written to, <code>readonly<\/code> tuples only permit reading from those positions.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> foo(<span class=\"pl-v\">pair<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #0000ff;\">string<\/span>, <span style=\"color: #0000ff;\">string<\/span>]) {\r\n    <span class=\"pl-c1\">console<\/span>.<span class=\"pl-c1\">log<\/span>(<span class=\"pl-smi\">pair<\/span>[<span style=\"color: #09885A;\">0<\/span>]);   <span style=\"color: #148A14;\">\/\/ okay<\/span>\r\n    <span class=\"pl-smi\">pair<\/span>[<span style=\"color: #09885A;\">1<\/span>] <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello!<span class=\"pl-pds\">\"<\/span><\/span>;     <span style=\"color: #148A14;\">\/\/ error<\/span>\r\n}<\/pre>\n<\/div>\n<p>The same way that ordinary tuples are types that extend from <code>Array<\/code> &#8211; a tuple with elements of type <code>T<\/code><sub><code>1<\/code><\/sub>, <code>T<\/code><sub><code>2<\/code><\/sub>, &#8230; <code>T<\/code><sub><code>n<\/code><\/sub> extends from <code>Array&lt;<\/code> <code>T<\/code><sub><code>1<\/code><\/sub> | <code>T<\/code><sub><code>2<\/code><\/sub> | &#8230; <code>T<\/code><sub><code>n<\/code><\/sub> <code>&gt;<\/code> &#8211; <code>readonly<\/code> tuples are types that extend from <code>ReadonlyArray<\/code>. So a <code>readonly<\/code> tuple with elements <code>T<\/code><sub><code>1<\/code><\/sub>, <code>T<\/code><sub><code>2<\/code><\/sub>, &#8230; <code>T<\/code><sub><code>n<\/code><\/sub> extends from <code>ReadonlyArray&lt;<\/code> <code>T<\/code><sub><code>1<\/code><\/sub> | <code>T<\/code><sub><code>2<\/code><\/sub> | &#8230; <code>T<\/code><sub><code>n<\/code><\/sub> <code>&gt;<\/code>.<\/p>\n<h3><\/h3>\n<h3><code>readonly<\/code> mapped type modifiers and <code>readonly<\/code> arrays<\/h3>\n<p>In earlier versions of TypeScript, we generalized mapped types to operate differently on array-like types. This meant that a mapped type like <code>Boxify<\/code> could work on arrays and tuples alike.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">Box<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; { value<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span> }\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Boxify<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    [<span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">T<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Box<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>[<span style=\"color: #267F99;\">K<\/span>]&gt;\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ { a: Box&lt;string&gt;, b: Box&lt;number&gt; }<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">A<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Boxify<\/span>&lt;{ a<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>, b<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Array&lt;Box&lt;number&gt;&gt;<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">B<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Boxify<\/span>&lt;<span style=\"color: #0000ff;\">number<\/span>[]&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ [Box&lt;string&gt;, Box&lt;number&gt;]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">C<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Boxify<\/span>&lt;[<span style=\"color: #0000ff;\">string<\/span>, <span style=\"color: #0000ff;\">boolean<\/span>]&gt;;<\/pre>\n<\/div>\n<p>Unfortunately, mapped types like the <code>Readonly<\/code> utility type were effectively no-ops on array and tuple types.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ lib.d.ts<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    <span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">T<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>[<span style=\"color: #267F99;\">K<\/span>]\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ How code acted *before* TypeScript 3.4<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ { readonly a: string, readonly b: number }<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">A<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;{ a<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>, b<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ number[]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">B<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;<span style=\"color: #0000ff;\">number<\/span>[]&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ [string, boolean]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">C<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;[<span style=\"color: #0000ff;\">string<\/span>, <span style=\"color: #0000ff;\">boolean<\/span>]&gt;;<\/pre>\n<\/div>\n<p>In TypeScript 3.4, the <code>readonly<\/code> modifier in a mapped type will automatically convert array-like types to their corresponding <code>readonly<\/code> counterparts.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ How code acts now *with* TypeScript 3.4<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ { readonly a: string, readonly b: number }<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">A<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;{ a<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>, b<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ readonly number[]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">B<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;<span style=\"color: #0000ff;\">number<\/span>[]&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ readonly [string, boolean]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">C<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Readonly<\/span>&lt;[<span style=\"color: #0000ff;\">string<\/span>, <span style=\"color: #0000ff;\">boolean<\/span>]&gt;;<\/pre>\n<\/div>\n<p>Similarly, you could write a utility type like <code>Writable<\/code> mapped type that strips away <code>readonly<\/code>-ness, and that would convert <code>readonly<\/code> array containers back to their mutable equivalents.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Writable<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    <span class=\"pl-k\">-<\/span><span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">T<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>[<span style=\"color: #267F99;\">K<\/span>]\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ { a: string, b: number }<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">A<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Writable<\/span>&lt;{\r\n    <span style=\"color: #0000ff;\">readonly<\/span> a<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n    <span style=\"color: #0000ff;\">readonly<\/span> b<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>\r\n}&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ number[]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">B<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Writable<\/span>&lt;<span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #0000ff;\">number<\/span>[]&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ [string, boolean]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">C<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Writable<\/span>&lt;<span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #0000ff;\">string<\/span>, <span style=\"color: #0000ff;\">boolean<\/span>]&gt;;<\/pre>\n<\/div>\n<h3><\/h3>\n<h3>Caveats<\/h3>\n<p>Despite its appearance, the <code>readonly<\/code> type modifier can only be used for syntax on array types and tuple types. It is not a general-purpose type operator.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">let<\/span> err1<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #267F99;\">Set<\/span>&lt;<span style=\"color: #0000ff;\">number<\/span>&gt;; <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> err2<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #267F99;\">Array<\/span>&lt;<span style=\"color: #0000ff;\">boolean<\/span>&gt;; <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> okay<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #0000ff;\">boolean<\/span>[]; <span style=\"color: #148A14;\">\/\/ works fine<\/span><\/pre>\n<\/div>\n<h2><\/h2>\n<h2><code>const<\/code> assertions<\/h2>\n<p>When declaring a mutable variable or property, TypeScript often <em>widens<\/em> values to make sure that we can assign things later on without writing an explicit type.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ hurray! we can assign to 'x' later on!<\/span>\r\n<span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>world<span class=\"pl-pds\">\"<\/span><\/span>;<\/pre>\n<\/div>\n<p>Technically, every literal value has a literal type. Above, the type <code>\"hello\"<\/code> got widened to the type <code>string<\/code> before inferring a type for <code>x<\/code>.<\/p>\n<p>One alternative view might be to say that <code>x<\/code> has the original literal type <code>\"hello\"<\/code> and that we can&#8217;t assign <code>\"world\"<\/code> later on like so:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">let<\/span> x<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n<span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>world<span class=\"pl-pds\">\"<\/span><\/span>;<\/pre>\n<\/div>\n<p>In this case, that seems extreme, but it can be useful in other situations. For example, TypeScripters often create objects that are meant to be used in discriminated unions.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Shape<\/span> <span class=\"pl-k\">=<\/span>\r\n    <span class=\"pl-k\">|<\/span> { kind<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>circle<span class=\"pl-pds\">\"<\/span><\/span>, radius<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }\r\n    <span class=\"pl-k\">|<\/span> { kind<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>square<span class=\"pl-pds\">\"<\/span><\/span>, sideLength<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> getShapes()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #267F99;\">Shape<\/span>[] {\r\n    <span style=\"color: #0000ff;\">let<\/span> result <span class=\"pl-k\">=<\/span> [\r\n        { kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>circle<span class=\"pl-pds\">\"<\/span><\/span>, radius: <span style=\"color: #09885A;\">100<\/span>, },\r\n        { kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>square<span class=\"pl-pds\">\"<\/span><\/span>, sideLength: <span style=\"color: #09885A;\">50<\/span>, },\r\n    ];\r\n    \r\n    <span style=\"color: #148A14;\">\/\/ Some terrible error message because TypeScript inferred<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ 'kind' to have the type 'string' instead of<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ either '\"circle\"' or '\"square\"'.<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">result<\/span>;\r\n}<\/pre>\n<\/div>\n<p>Mutability is one of the best heuristics of intent which TypeScript can use to determine when to widen (rather than analyzing our entire program).<\/p>\n<p>Unfortunately, as we saw in the last example, in JavaScript properties are mutable by default. This means that the language will often widen types undesirably, requiring explicit types in certain places.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> getShapes()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #267F99;\">Shape<\/span>[] {\r\n    <span style=\"color: #148A14;\">\/\/ This explicit annotation gives a hint<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ to avoid widening in the first place.<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> result<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">readonly<\/span> <span style=\"color: #267F99;\">Shape<\/span>[] <span class=\"pl-k\">=<\/span> [\r\n        { kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>circle<span class=\"pl-pds\">\"<\/span><\/span>, radius: <span style=\"color: #09885A;\">100<\/span>, },\r\n        { kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>square<span class=\"pl-pds\">\"<\/span><\/span>, sideLength: <span style=\"color: #09885A;\">50<\/span>, },\r\n    ];\r\n    \r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">result<\/span>;\r\n}<\/pre>\n<\/div>\n<p>Up to a certain point this is okay, but as our data structures get more and more complex, this becomes cumbersome.<\/p>\n<p>To solve this, TypeScript 3.4 introduces a new construct for literal values called <em><code>const<\/code><\/em> assertions. Its syntax is a type assertion with <code>const<\/code> in place of the type name (e.g. <code>123 as const<\/code>). When we construct new literal expressions with <code>const<\/code> assertions, we can signal to the language that<\/p>\n<ul>\n<li>no literal types in that expression should be widened (e.g. no going from <code>\"hello\"<\/code> to <code>string<\/code>)<\/li>\n<li>object literals get <code>readonly<\/code> properties<\/li>\n<li>array literals become <code>readonly<\/code> tuples<\/li>\n<\/ul>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ Type '10'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">10<\/span> <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Type 'readonly [10, 20]'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> y <span class=\"pl-k\">=<\/span> [<span style=\"color: #09885A;\">10<\/span>, <span style=\"color: #09885A;\">20<\/span>] <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Type '{ readonly text: \"hello\" }'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> z <span class=\"pl-k\">=<\/span> { text: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span> } <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span>;<\/pre>\n<\/div>\n<p>Outside of <code>.tsx<\/code> files, the angle bracket assertion syntax can also be used.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ Type '10'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> &lt;<span style=\"color: #0000ff;\">const<\/span>&gt;<span style=\"color: #09885A;\">10<\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Type 'readonly [10, 20]'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> y <span class=\"pl-k\">=<\/span> &lt;<span style=\"color: #0000ff;\">const<\/span>&gt;[<span style=\"color: #09885A;\">10<\/span>, <span style=\"color: #09885A;\">20<\/span>];\r\n\r\n<span style=\"color: #148A14;\">\/\/ Type '{ readonly text: \"hello\" }'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> z <span class=\"pl-k\">=<\/span> &lt;<span style=\"color: #0000ff;\">const<\/span>&gt;{ text: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span> };<\/pre>\n<\/div>\n<p>This feature often means that types that would otherwise be used just to hint immutability to the compiler can often be omitted.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ Works with no types referenced or declared.<\/span>\r\n<span style=\"color: #148A14;\">\/\/ We only needed a single const assertion.<\/span>\r\n<span style=\"color: #0000ff;\">function<\/span> getShapes() {\r\n    <span style=\"color: #0000ff;\">let<\/span> result <span class=\"pl-k\">=<\/span> [\r\n        { kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>circle<span class=\"pl-pds\">\"<\/span><\/span>, radius: <span style=\"color: #09885A;\">100<\/span>, },\r\n        { kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>square<span class=\"pl-pds\">\"<\/span><\/span>, sideLength: <span style=\"color: #09885A;\">50<\/span>, },\r\n    ] <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span>;\r\n    \r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">result<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #0000ff;\">const<\/span> shape <span style=\"color: #0000ff;\">of<\/span> <span class=\"pl-en\">getShapes<\/span>()) {\r\n    <span style=\"color: #148A14;\">\/\/ Narrows perfectly!<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">shape<\/span>.<span class=\"pl-smi\">kind<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>circle<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span class=\"pl-c1\">console<\/span>.<span class=\"pl-c1\">log<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>Circle radius<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-smi\">shape<\/span>.<span class=\"pl-smi\">radius<\/span>);\r\n    }\r\n    <span style=\"color: #0000ff;\">else<\/span> {\r\n        <span class=\"pl-c1\">console<\/span>.<span class=\"pl-c1\">log<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>Square side length<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-smi\">shape<\/span>.<span class=\"pl-smi\">sideLength<\/span>);\r\n    }\r\n}<\/pre>\n<\/div>\n<p>Notice the above needed no type annotations. The <code>const<\/code> assertion allowed TypeScript to take the most specific type of the expression.<\/p>\n<h3><\/h3>\n<h3>Caveats<\/h3>\n<p>One thing to note is that <code>const<\/code> assertions can only be applied immediately on simple literal expressions.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ Error!<\/span>\r\n<span style=\"color: #148A14;\">\/\/   A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> a <span class=\"pl-k\">=<\/span> (<span class=\"pl-c1\">Math<\/span>.<span class=\"pl-c1\">random<\/span>() <span class=\"pl-k\">&lt;<\/span> <span style=\"color: #09885A;\">0.5<\/span> <span class=\"pl-k\">?<\/span> <span style=\"color: #09885A;\">0<\/span> <span class=\"pl-k\">:<\/span> <span style=\"color: #09885A;\">1<\/span>) <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Works!<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> b <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">Math<\/span>.<span class=\"pl-c1\">random<\/span>() <span class=\"pl-k\">&lt;<\/span> <span style=\"color: #09885A;\">0.5<\/span> <span class=\"pl-k\">?<\/span>\r\n    <span style=\"color: #09885A;\">0<\/span> <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-k\">:<\/span>\r\n    <span style=\"color: #09885A;\">1<\/span> <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">const<\/span>;<\/pre>\n<\/div>\n<p>Another thing to keep in mind is that <code>const<\/code> contexts don&#8217;t immediately convert an expression to be fully immutable.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">let<\/span> arr <span class=\"pl-k\">=<\/span> [<span style=\"color: #09885A;\">1<\/span>, <span style=\"color: #09885A;\">2<\/span>, <span style=\"color: #09885A;\">3<\/span>, <span style=\"color: #09885A;\">4<\/span>];\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> foo <span class=\"pl-k\">=<\/span> {\r\n    name: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>foo<span class=\"pl-pds\">\"<\/span><\/span>,\r\n    contents: <span class=\"pl-smi\">arr<\/span>,\r\n};\r\n\r\n<span class=\"pl-smi\">foo<\/span>.<span class=\"pl-c1\">name<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>bar<span class=\"pl-pds\">\"<\/span><\/span>;   <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n<span class=\"pl-smi\">foo<\/span>.<span class=\"pl-smi\">contents<\/span> <span class=\"pl-k\">=<\/span> [];  <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n\r\n<span class=\"pl-smi\">foo<\/span>.<span class=\"pl-smi\">contents<\/span>.<span class=\"pl-c1\">push<\/span>(<span style=\"color: #09885A;\">5<\/span>); <span style=\"color: #148A14;\">\/\/ ...works!<\/span><\/pre>\n<\/div>\n<h2><\/h2>\n<h2>Type-checking for <code>globalThis<\/code><\/h2>\n<p>It can be surprisingly difficult to access or declare values in the global scope, perhaps because we&#8217;re writing our code in modules (whose local declarations don&#8217;t leak by default), or because we might have a local variable that shadows the name of a global value. In different environments, there are different ways to access what&#8217;s effectively the global scope &#8211; <code>global<\/code> in Node, <code>window<\/code>, <code>self<\/code>, or <code>frames<\/code> in the browser, or <code>this<\/code> in certain locations outside of strict mode. None of this is obvious, and often leaves users feeling unsure of whether they&#8217;re writing correct code.<\/p>\n<p>TypeScript 3.4 introduces support for type-checking ECMAScript&#8217;s new <code>globalThis<\/code> &#8211; a global variable that, well, refers to the global scope. Unlike the above solutions, <code>globalThis<\/code> provides a standard way for accessing the global scope which can be used across different environments.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ in a global file:<\/span>\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> abc <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">100<\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Refers to 'abc' from above.<\/span>\r\n<span class=\"pl-smi\">globalThis<\/span>.<span class=\"pl-smi\">abc<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">200<\/span>;<\/pre>\n<\/div>\n<p><code>globalThis<\/code> is also able to reflect whether or not a global variable was declared as a <code>const<\/code> by treating it as a <code>readonly<\/code> property when accessed.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">const<\/span> answer <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">42<\/span>;\r\n\r\n<span class=\"pl-smi\">globalThis<\/span>.<span class=\"pl-smi\">answer<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">333333<\/span>; <span style=\"color: #148A14;\">\/\/ error!<\/span><\/pre>\n<\/div>\n<p>It&#8217;s important to note that TypeScript doesn&#8217;t transform references to <code>globalThis<\/code> when compiling to older versions of ECMAScript. As such, unless you&#8217;re targeting evergreen browsers (which already support <code>globalThis<\/code>), you may want to <a href=\"https:\/\/github.com\/ljharb\/globalThis\">use an appropriate polyfill<\/a> instead.<\/p>\n<h2><\/h2>\n<h2>Convert to named parameters<\/h2>\n<p>Sometimes, parameter lists start getting unwieldy.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> updateOptions(\r\n    <span class=\"pl-v\">hue<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    <span class=\"pl-v\">saturation<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    <span class=\"pl-v\">brightness<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    <span class=\"pl-v\">positionX<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    <span class=\"pl-v\">positionY<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>\r\n    <span class=\"pl-en\">positionZ<\/span><span class=\"pl-k\">?:<\/span> <span style=\"color: #0000ff;\">number<\/span>) {\r\n    \r\n    <span style=\"color: #148A14;\">\/\/ ....<\/span>\r\n}<\/pre>\n<\/div>\n<p>In the above example, it&#8217;s way too easy for a caller to mix up the order of arguments given. A common JavaScript pattern is to instead use an &#8220;options object&#8221;, so that each option is explicitly named and order doesn&#8217;t ever matter. This emulates a feature that other languages have called &#8220;named parameters&#8221;.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">Options<\/span> {\r\n    hue<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    saturation<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    brightness<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    positionX<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>,\r\n    positionY<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>\r\n    positionZ<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>\r\n}\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> updateOptions(<span class=\"pl-v\">options<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Options<\/span> <span class=\"pl-k\">=<\/span> {}) {\r\n    \r\n    <span style=\"color: #148A14;\">\/\/ ....<\/span>\r\n}<\/pre>\n<\/div>\n<p>The TypeScript team doesn&#8217;t just work on a compiler &#8211; we also provide the functionality that editors use for rich features like completions, go to definition, and refactorings. In TypeScript 3.4, our intern <a href=\"https:\/\/github.com\/gabritto\">Gabriela Britto<\/a> has implemented a new refactoring to convert existing functions to use this &#8220;named parameters&#8221; pattern.<\/p>\n<p><a href=\"https:\/\/camo.githubusercontent.com\/921efb48cfe5c0bbc123119e0ee805d663553583\/68747470733a2f2f646576626c6f67732e6d6963726f736f66742e636f6d2f747970657363726970742f77702d636f6e74656e742f75706c6f6164732f73697465732f31312f323031392f30332f7265666163746f72546f4e616d6564506172616d734f626a6563742d332e342e676966\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/camo.githubusercontent.com\/921efb48cfe5c0bbc123119e0ee805d663553583\/68747470733a2f2f646576626c6f67732e6d6963726f736f66742e636f6d2f747970657363726970742f77702d636f6e74656e742f75706c6f6164732f73697465732f31312f323031392f30332f7265666163746f72546f4e616d6564506172616d734f626a6563742d332e342e676966\" alt=\"A refactoring being applied to a function to make it take named parameters.\" data-canonical-src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2019\/03\/refactorToNamedParamsObject-3.4.gif\" \/><\/a><\/p>\n<p>While we may change the name of the feature by our final 3.4 release and we believe there may be room for some of the ergonomics, we would love for you to try the feature out and give us your feedback.<\/p>\n<h2><\/h2>\n<h2>Breaking changes<\/h2>\n<h3><\/h3>\n<h3>Top-level <code>this<\/code> is now typed<\/h3>\n<p>The type of top-level <code>this<\/code> is now typed as <code>typeof globalThis<\/code> instead of <code>any<\/code>. As a consequence, you may receive errors for accessing unknown values on <code>this<\/code> under <code>noImplicitAny<\/code>.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #148A14;\">\/\/ previously okay in noImplicitAny, now an error<\/span>\r\n<span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">whargarbl<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">10<\/span>;<\/pre>\n<\/div>\n<p>Note that code compiled under <code>noImplicitThis<\/code> will not experience any changes here.<\/p>\n<h3><\/h3>\n<h3>Propagated generic type arguments<\/h3>\n<p>In certain cases, TypeScript 3.4&#8217;s improved inference might produce functions that are generic, rather than ones that take and return their constraints (usually <code>{}<\/code>).<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\"style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> compose&lt;<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #267F99;\">U<\/span>, <span style=\"color: #267F99;\">V<\/span>&gt;(<span class=\"pl-en\">f<\/span><span class=\"pl-k\">:<\/span> (<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>) <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #267F99;\">U<\/span>, <span class=\"pl-en\">g<\/span><span class=\"pl-k\">:<\/span> (<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">U<\/span>) <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #267F99;\">V<\/span>)<span class=\"pl-k\">:<\/span> (<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>) <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #267F99;\">V<\/span>;\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> list&lt;<span style=\"color: #267F99;\">T<\/span>&gt;(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>) { <span style=\"color: #0000ff;\">return<\/span> [<span class=\"pl-smi\">x<\/span>]; }\r\n<span style=\"color: #0000ff;\">function<\/span> box&lt;<span style=\"color: #267F99;\">T<\/span>&gt;(<span class=\"pl-v\">value<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>) { <span style=\"color: #0000ff;\">return<\/span> { <span class=\"pl-smi\">value<\/span> }; }\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> f <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">compose<\/span>(<span class=\"pl-smi\">list<\/span>, <span class=\"pl-smi\">box<\/span>);\r\n<span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">f<\/span>(<span style=\"color: #09885A;\">100<\/span>)\r\n\r\n<span style=\"color: #148A14;\">\/\/ In TypeScript 3.4, 'x.value' has the type<\/span>\r\n<span style=\"color: #148A14;\">\/\/<\/span>\r\n<span style=\"color: #148A14;\">\/\/   number[]<\/span>\r\n<span style=\"color: #148A14;\">\/\/<\/span>\r\n<span style=\"color: #148A14;\">\/\/ but it previously had the type<\/span>\r\n<span style=\"color: #148A14;\">\/\/<\/span>\r\n<span style=\"color: #148A14;\">\/\/   {}[]<\/span>\r\n<span style=\"color: #148A14;\">\/\/<\/span>\r\n<span style=\"color: #148A14;\">\/\/ So it's now an error to push in a string.<\/span>\r\n<span class=\"pl-smi\">x<\/span>.<span class=\"pl-c1\">value<\/span>.<span class=\"pl-c1\">push<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span>);<\/pre>\n<\/div>\n<p>An explicit type annotation on <code>x<\/code> can get rid of the error.<\/p>\n<h2><\/h2>\n<h2>What&#8217;s next?<\/h2>\n<p>TypeScript 3.4 is our first release that has had an <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/issues\/30281\">iteration plan<\/a> outlining our plans for this release, which is meant to align with <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/issues\/29288\">our 6-month roadmap<\/a>. You can keep an eye on both of those, and on our rolling <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">feature roadmap page<\/a> for any upcoming work.<\/p>\n<p>Right now we&#8217;re looking forward to hearing about your experience with the RC, so give it a shot now and let us know your thoughts!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re happy to announce the availability of our release candidate (RC) of TypeScript 3.4. Our hope is to collect feedback and early issues to ensure our final release is simple to pick up and use right away. To get started using the RC, you can get it through NuGet, or use npm with the [&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-2161","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 our release candidate (RC) of TypeScript 3.4. Our hope is to collect feedback and early issues to ensure our final release is simple to pick up and use right away. To get started using the RC, you can get it through NuGet, or use npm with the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2161","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=2161"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2161\/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=2161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=2161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=2161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}