{"id":2209,"date":"2019-05-16T14:55:39","date_gmt":"2019-05-16T22:55:39","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=2209"},"modified":"2019-05-16T16:36:55","modified_gmt":"2019-05-17T00:36:55","slug":"announcing-typescript-3-5-rc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-3-5-rc\/","title":{"rendered":"Announcing TypeScript 3.5 RC"},"content":{"rendered":"<p>Today we&#8217;re happy to announce the availability of our release candidate (RC) of TypeScript 3.5. 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>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-350rc-vs2017\" rel=\"nofollow\">Downloading for Visual Studio 2019\/2017<\/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 explore what&#8217;s new in 3.5!<\/p>\n<ul>\n<li><a href=\"#speed-improvements\">Speed improvements<\/a><\/li>\n<li><a href=\"#the-omit-helper-type\">The <code>Omit<\/code> helper type<\/a><\/li>\n<li><a href=\"#improved-excess-property-checks-in-union-types\">Improved excess property checks in union types<\/a><\/li>\n<li><a href=\"#the---allowumdglobalaccess-flag\">The <code>--allowUmdGlobalAccess<\/code> flag<\/a><\/li>\n<li><a href=\"#smarter-union-type-checking\">Smarter union type checking<\/a><\/li>\n<li><a href=\"#higher-order-type-inference-from-generic-constructors\">Higher order type inference from generic constructors<\/a><\/li>\n<li><a href=\"#breaking-changes\">Breaking changes<\/a><\/li>\n<\/ul>\n<h2 id=\"speed-improvements\">Speed improvements<\/h2>\n<p>TypeScript 3.5 introduces several optimizations around type-checking and incremental builds.<\/p>\n<h3 id=\"type-checking-speed-ups\">Type-checking speed-ups<\/h3>\n<p>Much of the expressivity of our type system comes with a cost &#8211; any more work that we expect the compiler to do translates to longer compile times. Unfortunately, as part of a bug fix in TypeScript 3.4 we accidentally introduced a regression that could lead to an explosion in how much work the type-checker did, and in turn, type-checking time. The most-impacted set of users were those using the styled-components library. This regression was serious not just because it led to much higher build times for TypeScript code, but because editor operations for both TypeScript and JavaScript users became unbearably slow.<\/p>\n<p>Over this past release, we focused heavily on optimizing certain code paths and stripping down certain functionality to the point where TypeScript 3.5 is actually <em>faster<\/em> than TypeScript 3.3 for many incremental checks. Not only have compile times fallen compared to 3.4, but code completion and any other editor operations should be much snappier too.<\/p>\n<p>If you haven&#8217;t upgraded to TypeScript 3.4 due to these regressions, we would value your feedback to see whether TypeScript 3.5 addresses your performance concerns!<\/p>\n<h3 id=\"--incremental-improvements\"><code>--incremental<\/code> improvements<\/h3>\n<p>TypeScript 3.4 introduced a new <code>--incremental<\/code> compiler option. This option saves a bunch of information to a <code>.tsbuildinfo<\/code> file that can be used to speed up subsequent calls to <code>tsc<\/code>.<\/p>\n<p>TypeScript 3.5 includes several optimizations to caching how the state of the world was calculated &#8211; compiler settings, why files were looked up, where files were found, etc. In scenarios involving hundreds of projects using TypeScript&#8217;s project references in <code>--build<\/code> mode, <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/31101\">we&#8217;ve found that the amount of time rebuilding can be reduced by as much as 68% compared to TypeScript 3.4<\/a>!<\/p>\n<p>For more details, you can see the pull requests to<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/31100\">cache module resolution<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/31101\">cache settings calculated from <code>tsconfig.json<\/code><\/a><\/li>\n<\/ul>\n<h2 id=\"the-omit-helper-type\">The <code>Omit<\/code> helper type<\/h2>\n<p>Much of the time, we want to create an object that omits certain properties. It turns out that we can express types like that using TypeScript&#8217;s built-in <code>Pick<\/code> and <code>Exclude<\/code> helpers. For example, if we wanted to define a <code>Person<\/code> that has no <code>location<\/code> property, we could write the following:<\/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;\">Person<\/span> <span class=\"pl-k\">=<\/span> {\r\n    name<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n    age<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n    location<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n};\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">RemainingKeys<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Exclude<\/span>&lt;<span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">Person<\/span>, <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>location<span class=\"pl-pds\">\"<\/span><\/span>&gt;;\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">QuantumPerson<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Pick<\/span>&lt;<span style=\"color: #267F99;\">Person<\/span>, <span style=\"color: #267F99;\">RemainingKeys<\/span>&gt;;\r\n\r\n<span style=\"color: #148A14;\">\/\/ equivalent to<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">QuantumPerson<\/span> <span class=\"pl-k\">=<\/span> {\r\n    name<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n    age<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n};<\/pre>\n<\/div>\n<p>Here we &#8220;subtracted&#8221; <code>\"location\"<\/code> from the set of properties of <code>Person<\/code> using the <code>Exclude<\/code> helper type. We then picked them right off of <code>Person<\/code> using the <code>Pick<\/code> helper type.<\/p>\n<p>It turns out this type of operation comes up frequently enough that users will write a helper type to do exactly this:<\/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;\">Omit<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #0000ff;\">any<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Pick<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #267F99;\">Exclude<\/span>&lt;<span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #267F99;\">K<\/span>&gt;&gt;;<\/pre>\n<\/div>\n<p>Instead of making everyone define their own version of <code>Omit<\/code>, TypeScript 3.5 will include its own in <code>lib.d.ts<\/code> which can be used anywhere. The compiler itself will use this <code>Omit<\/code> type to express types created through object rest destructuring declarations on generics.<\/p>\n<p>For more details, <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/30552\">see the pull request on GitHub to add <code>Omit<\/code><\/a>, as well as <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/31134\">the change to use <code>Omit<\/code> for object rest<\/a>.<\/p>\n<h3 id=\"improved-excess-property-checks-in-union-types\">Improved excess property checks in union types<\/h3>\n<p>TypeScript has a feature called <em>excess property checking<\/em> in object literals. This feature is meant to detect typos for when a type isn&#8217;t expecting a specific property.<\/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;\">Style<\/span> <span class=\"pl-k\">=<\/span> {\r\n    alignment<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>,\r\n    color<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>\r\n};\r\n\r\n<span style=\"color: #0000ff;\">const<\/span> s<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Style<\/span> <span class=\"pl-k\">=<\/span> {\r\n    alignment: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>center<span class=\"pl-pds\">\"<\/span><\/span>,\r\n    colour: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>grey<span class=\"pl-pds\">\"<\/span><\/span>\r\n<span style=\"color: #148A14;\">\/\/  ^^^^^^ error! <\/span>\r\n};<\/pre>\n<\/div>\n<p>In TypeScript 3.4 and earlier, certain excess properties were allowed in situations where they really shouldn&#8217;t have been. For instance, TypeScript 3.4 permitted the incorrect <code>name<\/code> property in the object literal even though its types don&#8217;t match between <code>Point<\/code> and <code>Label<\/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;\">type<\/span> <span style=\"color: #267F99;\">Point<\/span> <span class=\"pl-k\">=<\/span> {\r\n    x<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n    y<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n};\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Label<\/span> <span class=\"pl-k\">=<\/span> {\r\n    name<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n};\r\n\r\n<span style=\"color: #0000ff;\">const<\/span> thing<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Point<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">Label<\/span> <span class=\"pl-k\">=<\/span> {\r\n    x: <span style=\"color: #09885A;\">0<\/span>,\r\n    y: <span style=\"color: #09885A;\">0<\/span>,\r\n    name: <span style=\"color: #0000ff;\">true<\/span> <span style=\"color: #148A14;\">\/\/ uh-oh!<\/span>\r\n};<\/pre>\n<\/div>\n<p>Previously, a non-disciminated union wouldn&#8217;t have <em>any<\/em> excess property checking done on its members, and as a result, the incorrectly typed <code>name<\/code> property slipped by.<\/p>\n<p>In TypeScript 3.5, the type-checker at least verifies that all the provided properties belong to <em>some<\/em> union member and have the appropriate type, meaning that the sample above correctly issues an error.<\/p>\n<p>Note that partial overlap is still permitted as long as the property types are valid.<\/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> pl<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Point<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">Label<\/span> <span class=\"pl-k\">=<\/span> {\r\n    x: <span style=\"color: #09885A;\">0<\/span>,\r\n    y: <span style=\"color: #09885A;\">0<\/span>,\r\n    name: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>origin<span class=\"pl-pds\">\"<\/span><\/span> <span style=\"color: #148A14;\">\/\/ okay<\/span>\r\n};<\/pre>\n<\/div>\n<h2 id=\"the---allowumdglobalaccess-flag\">The <code>--allowUmdGlobalAccess<\/code> flag<\/h2>\n<p>In TypeScript 3.5, you can now reference UMD global declarations like<\/p>\n<pre><code>export as namespace foo;\r\n<\/code><\/pre>\n<p>from anywhere &#8211; even modules &#8211; using the new <code>--allowUmdGlobalAccess<\/code> flag.<\/p>\n<p>This feature might require some background if you&#8217;re not familiar with UMD globals in TypeScript. A while back, JavaScript libraries were often published as global variables with properties tacked on &#8211; you sort of hoped that nobody picked a library name that was identical to yours. Over time, authors of modern JavaScript libraries started publishing using module systems to prevent some of these issues. While module systems alleviated certain classes of issues, they did leave users who were used to using global variables out in the rain.<\/p>\n<p>As a work-around, many libraries are authored in a way that define a global object if a module loader isn&#8217;t available at runtime. This is typically leveraged when users target a module format called &#8220;UMD&#8221;, and as such, TypeScript has a way to describe this pattern which we&#8217;ve called &#8220;UMD global namespaces&#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;\">export<\/span> <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">namespace<\/span> <span class=\"pl-en\">preact<\/span>;<\/pre>\n<\/div>\n<p>Whenever you&#8217;re in a script file (a non-module file), you&#8217;ll be able to access one of these UMD globals.<\/p>\n<p>So what&#8217;s the problem? Well, not all libraries <em>conditionally<\/em> set their global declarations. Some just <em>always<\/em> create a global in addition to registering with the module system. We decided to err on the more conservative side, and many of us felt that if a library <em>could<\/em> be imported, that was probably the the intent of the author.<\/p>\n<p>In reality, we received a lot of feedback that users were writing modules where some libraries were consumed as globals, and others were consumed through imports. So in the interest of making those users&#8217; lives easier, we&#8217;ve introduced the <code>allowUmdGlobalAccess<\/code> flag in TypeScript 3.5.<\/p>\n<p>For more details, <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/30776\/files\">see the pull request on GitHub<\/a>.<\/p>\n<h2 id=\"smarter-union-type-checking\">Smarter union type checking<\/h2>\n<p>When checking against union types, TypeScript typically compares each constituent type in isolation. For example, take the following 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;\">type<\/span> <span style=\"color: #267F99;\">S<\/span> <span class=\"pl-k\">=<\/span> { done<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>, value<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">T<\/span> <span class=\"pl-k\">=<\/span>\r\n    <span class=\"pl-k\">|<\/span> { done<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">false<\/span>, value<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }\r\n    <span class=\"pl-k\">|<\/span> { done<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">true<\/span>, value<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> };\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> source<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">S<\/span>;\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> target<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>;\r\n\r\n<span class=\"pl-smi\">target<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">source<\/span>;<\/pre>\n<\/div>\n<p>Assigning <code>source<\/code> to <code>target<\/code> involves checking whether the type of <code>source<\/code> is assignable to <code>target<\/code>. That in turn means that TypeScript needs to check whether <code>S<\/code>:<\/p>\n<pre><code>{ done: boolean, value: number }\r\n<\/code><\/pre>\n<p>is assignable to <code>T<\/code>:<\/p>\n<pre><code>{ done: false, value: number } | { done: true, value: number }\r\n<\/code><\/pre>\n<p>Prior to TypeScript 3.5, the check in this specific example would fail, because <code>S<\/code> isn&#8217;t assignable to <code>{ done: false, value: number }<\/code> nor <code>{ done: true, value: number }<\/code>. Why? Because the <code>done<\/code> property in <code>S<\/code> isn&#8217;t specific enough &#8211; it&#8217;s <code>boolean<\/code>whereas each constituent of <code>T<\/code> has a <code>done<\/code> property that&#8217;s specifically <code>true<\/code> or <code>false<\/code>. That&#8217;s what we meant by each constituent type being checked in isolation: TypeScript doesn&#8217;t just union each property together and see if <code>S<\/code> is assignable to that. If it did, some bad code could get through like the following:<\/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;\">Foo<\/span> {\r\n    kind<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>foo<span class=\"pl-pds\">\"<\/span><\/span>;\r\n    value<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">Bar<\/span> {\r\n    kind<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>bar<span class=\"pl-pds\">\"<\/span><\/span>;\r\n    value<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> doSomething(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Foo<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">Bar<\/span>) {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">x<\/span>.<span class=\"pl-smi\">kind<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>foo<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span class=\"pl-smi\">x<\/span>.<span class=\"pl-c1\">value<\/span>.<span class=\"pl-c1\">toLowerCase<\/span>();\r\n    }\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ uh-oh - luckily TypeScript errors here!<\/span>\r\n<span class=\"pl-en\">doSomething<\/span>({\r\n    kind: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>foo<span class=\"pl-pds\">\"<\/span><\/span>,\r\n    value: <span style=\"color: #09885A;\">123<\/span>,\r\n});<\/pre>\n<\/div>\n<p>So clearly this behavior is good for some set of cases. Was TypeScript being helpful in the original example though? Not really. If you figure out the precise type of any possible value of <code>S<\/code>, you can actually see that it matches the types in <code>T<\/code>exactly.<\/p>\n<p>That&#8217;s why in TypeScript 3.5, when assigning to types with discriminant properties like in <code>T<\/code>, the language actually <em>will<\/em> go further and decompose types like <code>S<\/code> into a union of every possible inhabitant type. In this case, since <code>boolean<\/code> is a union of <code>true<\/code> and <code>false<\/code>, <code>S<\/code> will be viewed as a union of <code>{ done: false, value: number }<\/code> and <code>{ done: true, value: number }<\/code>.<\/p>\n<p>For more details, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/30779\">see the original pull request on GitHub<\/a>.<\/p>\n<h2 id=\"higher-order-type-inference-from-generic-constructors\">Higher order type inference from generic constructors<\/h2>\n<p>In TypeScript 3.4, we improved inference for when generic functions that return functions 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;\">function<\/span> compose&lt;<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #267F99;\">U<\/span>, <span style=\"color: #267F99;\">V<\/span>&gt;(\r\n    <span class=\"pl-en\">f<\/span><span class=\"pl-k\">:<\/span> (<span class=\"pl-v\">x<\/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\">y<\/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\">x<\/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;\">return<\/span> <span class=\"pl-v\">x<\/span> <span class=\"pl-k\">=&gt;<\/span> <span class=\"pl-en\">g<\/span>(<span class=\"pl-en\">f<\/span>(<span class=\"pl-smi\">x<\/span>))\r\n}<\/pre>\n<\/div>\n<p>took other generic functions as arguments, 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;\">function<\/span> arrayify&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 class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>[] {\r\n    <span style=\"color: #0000ff;\">return<\/span> [<span class=\"pl-smi\">x<\/span>];\r\n}\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Box<\/span>&lt;<span style=\"color: #267F99;\">U<\/span>&gt; <span class=\"pl-k\">=<\/span> { value<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">U<\/span> }\r\n<span style=\"color: #0000ff;\">function<\/span> boxify&lt;<span style=\"color: #267F99;\">U<\/span>&gt;(<span class=\"pl-v\">y<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">U<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Box<\/span>&lt;<span style=\"color: #267F99;\">U<\/span>&gt; {\r\n    <span style=\"color: #0000ff;\">return<\/span> { value: <span class=\"pl-smi\">y<\/span> };\r\n}\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> newFn <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">compose<\/span>(<span class=\"pl-smi\">arrayify<\/span>, <span class=\"pl-smi\">boxify<\/span>);<\/pre>\n<\/div>\n<p>Instead of a relatively useless type like <code>(x: {}) =&gt; Box&lt;{}[]&gt;<\/code>, which older versions of the language would infer, TypeScript 3.4&#8217;s inference allows <code>newFn<\/code> to be generic. Its new type is <code>&lt;T&gt;(x: T) =&gt; Box&lt;T[]&gt;<\/code>.<\/p>\n<p>TypeScript 3.5 generalizes this behavior to work on constructor functions as well.<\/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;\">class<\/span> <span style=\"color: #267F99;\">Box<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; {\r\n    kind<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>box<span class=\"pl-pds\">\"<\/span><\/span>;\r\n    value<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>;\r\n    <span style=\"color: #0000ff;\">constructor<\/span>(<span class=\"pl-v\">value<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>) {\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-c1\">value<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">value<\/span>;\r\n    }\r\n}\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Bag<\/span>&lt;<span style=\"color: #267F99;\">U<\/span>&gt; {\r\n    kind<span class=\"pl-k\">:<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>bag<span class=\"pl-pds\">\"<\/span><\/span>;\r\n    value<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">U<\/span>;\r\n    <span style=\"color: #0000ff;\">constructor<\/span>(<span class=\"pl-v\">value<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">U<\/span>) {\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-c1\">value<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">value<\/span>;\r\n    }\r\n}\r\n\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> composeCtor&lt;<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #267F99;\">U<\/span>, <span style=\"color: #267F99;\">V<\/span>&gt;(\r\n    <span class=\"pl-v\">F<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">new<\/span> (<span class=\"pl-v\">x<\/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-v\">G<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">new<\/span> (<span class=\"pl-v\">y<\/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\">x<\/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;\">return<\/span> <span class=\"pl-v\">x<\/span> <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">G<\/span>(<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">F<\/span>(<span class=\"pl-smi\">x<\/span>))\r\n}\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> f <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">composeCtor<\/span>(<span class=\"pl-smi\">Box<\/span>, <span class=\"pl-smi\">Bag<\/span>); <span style=\"color: #148A14;\">\/\/ has type '&lt;T&gt;(x: T) =&gt; Bag&lt;Box&lt;T&gt;&gt;'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> a <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">f<\/span>(<span style=\"color: #09885A;\">1024<\/span>); <span style=\"color: #148A14;\">\/\/ has type 'Bag&lt;Box&lt;number&gt;&gt;'<\/span><\/pre>\n<\/div>\n<p>In addition to compositional patterns like the above, this new inference on generic constructors means that functions that operate on class components in certain UI libraries like React can more correctly operate on generic class components.<\/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;\">ComponentClass<\/span>&lt;<span style=\"color: #267F99;\">P<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #0000ff;\">new<\/span> (<span class=\"pl-v\">props<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">P<\/span>) <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #267F99;\">Component<\/span>&lt;<span style=\"color: #267F99;\">P<\/span>&gt;;\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Component<\/span>&lt;<span style=\"color: #267F99;\">P<\/span>&gt; {\r\n    props<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">P<\/span>;\r\n    <span style=\"color: #0000ff;\">constructor<\/span>(<span class=\"pl-v\">props<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">P<\/span>);\r\n}\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> myHoc&lt;<span style=\"color: #267F99;\">P<\/span>&gt;(<span class=\"pl-v\">C<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">ComponentClass<\/span>&lt;<span style=\"color: #267F99;\">P<\/span>&gt;)<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">ComponentClass<\/span>&lt;<span style=\"color: #267F99;\">P<\/span>&gt;;\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">NestedProps<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> { foo<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>, stuff<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span> };\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">GenericComponent<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267F99;\">Component<\/span>&lt;<span style=\"color: #267F99;\">NestedProps<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt;&gt; {\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ type is 'new &lt;T&gt;(props: NestedProps&lt;T&gt;) =&gt; Component&lt;NestedProps&lt;T&gt;&gt;'<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> GenericComponent2 <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">myHoc<\/span>(<span class=\"pl-smi\">GenericComponent<\/span>);<\/pre>\n<\/div>\n<p>To learn more, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/31116\">check out the original pull request on GitHub<\/a>.<\/p>\n<h2 id=\"breaking-changes\">Breaking changes<\/h2>\n<h3 id=\"generic-type-parameters-are-implicitly-constrained-to-unknown\">Generic type parameters are implicitly constrained to <code>unknown<\/code><\/h3>\n<p>In TypeScript 3.5, <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/30637\">generic type parameters without an explicit constraint are now implicitly constrained to <code>unknown<\/code><\/a>, whereas previously the implicit constraint of type parameters was the empty object type <code>{}<\/code>.<\/p>\n<p>In practice, <code>{}<\/code> and <code>unknown<\/code> are pretty similar, but there are a few key differences:<\/p>\n<ul>\n<li><code>{}<\/code> can be indexed with a string (<code>k[\"foo\"]<\/code>), though this is an implicit <code>any<\/code> error under <code>--noImplicitAny<\/code>.<\/li>\n<li><code>{}<\/code> is assumed to not be <code>null<\/code> or <code>undefined<\/code>, whereas <code>unknown<\/code> is possibly one of those values.<\/li>\n<li><code>{}<\/code> is assignable to <code>object<\/code>, but <code>unknown<\/code> is not.<\/li>\n<\/ul>\n<p>The decision to switch to <code>unknown<\/code> is rooted that it is more correct for unconstrained generics &#8211; there&#8217;s no telling how a generic type will be instantiated.<\/p>\n<p>On the caller side, this typically means that assignment to <code>object<\/code> will fail, and methods on <code>Object<\/code> like <code>toString<\/code>, <code>toLocaleString<\/code>, <code>valueOf<\/code>, <code>hasOwnProperty<\/code>, <code>isPrototypeOf<\/code>, and <code>propertyIsEnumerable<\/code> will no longer be available.<\/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&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 class=\"pl-k\">:<\/span> [<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #0000ff;\">string<\/span>] {\r\n    <span style=\"color: #0000ff;\">return<\/span> [<span class=\"pl-smi\">x<\/span>, <span class=\"pl-smi\">x<\/span>.<span class=\"pl-c1\">toString<\/span>()]\r\n    <span style=\"color: #148A14;\">\/\/           ~~~~~~~~ error! Property 'toString' does not exist on type 'T'.<\/span>\r\n}<\/pre>\n<\/div>\n<p>As a workaround, you can add an explicit constraint of <code>{}<\/code> to a type parameter to get the old behavior.<\/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;\">\/\/             vvvvvvvvvv<\/span>\r\n<span style=\"color: #0000ff;\">function<\/span> foo&lt;<span style=\"color: #267F99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> {}&gt;(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>)<span class=\"pl-k\">:<\/span> [<span style=\"color: #267F99;\">T<\/span>, <span style=\"color: #0000ff;\">string<\/span>] {\r\n    <span style=\"color: #0000ff;\">return<\/span> [<span class=\"pl-smi\">x<\/span>, <span class=\"pl-smi\">x<\/span>.<span class=\"pl-c1\">toString<\/span>()]\r\n}<\/pre>\n<\/div>\n<p>From the caller side, failed inferences for generic type arguments will result in <code>unknown<\/code> instead of <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;\">function<\/span> parse&lt;<span style=\"color: #267F99;\">T<\/span>&gt;(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span> {\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-c1\">JSON<\/span>.<span class=\"pl-c1\">parse<\/span>(<span class=\"pl-smi\">x<\/span>);\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ k has type 'unknown' - previously, it was '{}'.<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> k <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">parse<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>...<span class=\"pl-pds\">\"<\/span><\/span>);<\/pre>\n<\/div>\n<p>As a workaround, you can provide an explicit type argument:<\/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;\">\/\/ 'k' now has type '{}'<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> k <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">parse<\/span>&lt;{}&gt;(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>...<span class=\"pl-pds\">\"<\/span><\/span>);<\/pre>\n<\/div>\n<h3 id=\"-k-string-unknown--is-no-longer-a-wildcard-assignment-target\"><code>{ [k: string]: unknown }<\/code> is no longer a wildcard assignment target<\/h3>\n<p>The index signature <code>{ [s: string]: any }<\/code> in TypeScript behaves specially: it&#8217;s a valid assignment target for any object type. This is a special rule, since types with index signatures don&#8217;t normally produce this behavior.<\/p>\n<p>Since its introduction, the type <code>unknown<\/code> in an index signature behaved the same way:<\/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> dict<span class=\"pl-k\">:<\/span> { [<span class=\"pl-v\">s<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">unknown<\/span> };\r\n<span style=\"color: #148A14;\">\/\/ Was okay<\/span>\r\n<span class=\"pl-en\">dict<\/span> <span class=\"pl-k\">=<\/span> () <span class=\"pl-k\">=&gt;<\/span> {};<\/pre>\n<\/div>\n<p>In general this rule makes sense; the implied constraint of &#8220;all its properties are some subtype of <code>unknown<\/code>&#8221; is trivially true of any object type. However, in TypeScript 3.5, this special rule is removed for <code>{ [s: string]: unknown }<\/code>.<\/p>\n<p>This was a necessary change because of the change from <code>{}<\/code> to <code>unknown<\/code> when generic inference has no candidates. Consider this 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> someFunc()<span class=\"pl-k\">:<\/span> <span class=\"pl-c1\">void<\/span>;\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> fn&lt;<span style=\"color: #267F99;\">T<\/span>&gt;(<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> { [<span class=\"pl-v\">k<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span> })<span class=\"pl-k\">:<\/span> <span class=\"pl-c1\">void<\/span>;\r\n<span class=\"pl-en\">fn<\/span>(<span class=\"pl-smi\">someFunc<\/span>);<\/pre>\n<\/div>\n<p>In TypeScript 3.4, the following sequence occurred:<\/p>\n<ul>\n<li>No candidates were found for <code>T<\/code><\/li>\n<li><code>T<\/code> is selected to be <code>{}<\/code><\/li>\n<li><code>someFunc<\/code> isn&#8217;t assignable to <code>arg<\/code> because there are no special rules allowing arbitrary assignment to <code>{ [k: string]: {} }<\/code><\/li>\n<li>The call is correctly rejected<\/li>\n<\/ul>\n<p>Due to changes around unconstrained type parameters falling back to <code>unknown<\/code> (see above), <code>arg<\/code> would have had the type <code>{ [k: string]: unknown }<\/code>, which anything is assignable to, so the call would have incorrectly been allowed. That&#8217;s why TypeScript 3.5 removes the specialized assignability rule to permit assignment to <code>{ [k: string]: unknown }<\/code>.<\/p>\n<p>Note that fresh object literals are still exempt from this check.<\/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> obj <span class=\"pl-k\">=<\/span> { m: <span style=\"color: #09885A;\">10<\/span> }; \r\n<span style=\"color: #148A14;\">\/\/ okay<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> dict<span class=\"pl-k\">:<\/span> { [<span class=\"pl-v\">s<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">unknown<\/span> } <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">obj<\/span>;<\/pre>\n<\/div>\n<p>Depending on the intended behavior of <code>{ [s: string]: unknown }<\/code>, several alternatives are available:<\/p>\n<ul>\n<li><code>{ [s: string]: any }<\/code><\/li>\n<li><code>{ [s: string]: {} }<\/code><\/li>\n<li><code>object<\/code><\/li>\n<li><code>unknown<\/code><\/li>\n<li><code>any<\/code><\/li>\n<\/ul>\n<p>We recommend sketching out your desired use cases and seeing which one is the best option for your particular use case.<\/p>\n<h3><a id=\"user-content-improved-excess-property-checks-in-union-types-1\" class=\"anchor\" href=\"https:\/\/github.com\/microsoft\/TypeScript-Blog-Posts\/blob\/1007609d89c8c2bf2658aa2c36788b306d97b157\/posts\/TypeScript%203.5\/RC\/Post.md#improved-excess-property-checks-in-union-types-1\" aria-hidden=\"true\"><\/a>Improved excess property checks in union types<\/h3>\n<p>As mentioned above, TypeScript 3.5 is stricter about excess property checks on constituents of union types.<\/p>\n<p>We have not witnessed examples where this checking hasn&#8217;t caught legitimate issues, but in a pinch, any of the workarounds to disable excess property checking will apply:<\/p>\n<ul>\n<li>Add a type assertion onto the object (e.g. <code>{ myProp: SomeType } as ExpectedType<\/code>)<\/li>\n<li>Add an index signature to the expected type to signal that unspecified properties are expected (e.g. <code>interface ExpectedType { myProp: SomeType; [prop: string]: unknown }<\/code>)<\/li>\n<\/ul>\n<h3 id=\"fixes-to-unsound-writes-to-indexed-access-types\">Fixes to unsound writes to indexed access types<\/h3>\n<p>TypeScript allows you to represent the operation of accessing a property of an object via the name of that property:<\/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;\">A<\/span> <span class=\"pl-k\">=<\/span> {\r\n    s<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n    n<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n};\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> read&lt;<span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">A<\/span>&gt;(<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span>, <span class=\"pl-v\">key<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">K<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span>[<span style=\"color: #267F99;\">K<\/span>] {\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">arg<\/span>[<span class=\"pl-smi\">key<\/span>];\r\n} \r\n\r\n<span style=\"color: #0000ff;\">const<\/span> a<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span> <span class=\"pl-k\">=<\/span> { s: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><\/span>, n: <span style=\"color: #09885A;\">0<\/span> };\r\n<span style=\"color: #0000ff;\">const<\/span> x <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">read<\/span>(<span class=\"pl-smi\">a<\/span>, <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>s<span class=\"pl-pds\">\"<\/span><\/span>); <span style=\"color: #148A14;\">\/\/ x: string<\/span><\/pre>\n<\/div>\n<p>While commonly used for reading values from an object, you can also use this for writes:<\/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> write&lt;<span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">A<\/span>&gt;(<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span>, <span class=\"pl-v\">key<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">K<\/span>, <span class=\"pl-v\">value<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span>[<span style=\"color: #267F99;\">K<\/span>])<span class=\"pl-k\">:<\/span> <span class=\"pl-c1\">void<\/span> {\r\n    <span class=\"pl-smi\">arg<\/span>[<span class=\"pl-smi\">key<\/span>] <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">value<\/span>;\r\n}<\/pre>\n<\/div>\n<p>In TypeScript 3.4, the logic used to validate a <em>write<\/em> was much too permissive:<\/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> write&lt;<span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">A<\/span>&gt;(<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span>, <span class=\"pl-v\">key<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">K<\/span>, <span class=\"pl-v\">value<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">A<\/span>[<span style=\"color: #267F99;\">K<\/span>])<span class=\"pl-k\">:<\/span> <span class=\"pl-c1\">void<\/span> {\r\n    <span style=\"color: #148A14;\">\/\/ ???<\/span>\r\n    <span class=\"pl-smi\">arg<\/span>[<span class=\"pl-smi\">key<\/span>] <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>hello, world<span class=\"pl-pds\">\"<\/span><\/span>;\r\n}\r\n<span style=\"color: #148A14;\">\/\/ Breaks the object by putting a string where a number should be<\/span>\r\n<span class=\"pl-en\">write<\/span>(<span class=\"pl-smi\">a<\/span>, <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>n<span class=\"pl-pds\">\"<\/span><\/span>, <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>oops!<span class=\"pl-pds\">\"<\/span><\/span>);<\/pre>\n<\/div>\n<p>In TypeScript 3.5, this logic is fixed and the above sample correctly issues an error.<\/p>\n<p>Most instances of this error represent potential errors in the relevant code. If you are convinced that you are not dealing with an error, you can use a type assertion instead.<\/p>\n<h3 id=\"libdts-includes-the-omit-helper-type\"><code>lib.d.ts<\/code> includes the <code>Omit<\/code> helper type<\/h3>\n<p>TypeScript 3.5 includes a new <code>Omit<\/code> helper type. As a result, any global declarations of <code>Omit<\/code> included in your project will result in the following error message:<\/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 class=\"pl-smi\">Duplicate<\/span> <span class=\"pl-smi\">identifier<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">'<\/span>Omit<span class=\"pl-pds\">'<\/span><\/span>.<\/pre>\n<\/div>\n<p>Two workarounds may be used here:<\/p>\n<ol>\n<li>Delete the duplicate declaration and use the one provided in <code>lib.d.ts<\/code>.<\/li>\n<li>Export the existing declaration from a module file or a namespace to avoid a global collision. Existing usages can use an <code>import<\/code> or explicit reference to your project&#8217;s old <code>Omit<\/code> type.<\/li>\n<\/ol>\n<h3><a id=\"user-content-objectkeys-rejects-primitives-in-es5\" class=\"anchor\" href=\"https:\/\/github.com\/microsoft\/TypeScript-Blog-Posts\/blob\/1007609d89c8c2bf2658aa2c36788b306d97b157\/posts\/TypeScript%203.5\/RC\/Post.md#objectkeys-rejects-primitives-in-es5\" aria-hidden=\"true\"><\/a><code>Object.keys<\/code> rejects primitives in ES5<\/h3>\n<p>In ECMAScript 5 environments, <code>Object.keys<\/code> throws an exception if passed any non-<code>object<\/code> argument:<\/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;\">\/\/ Throws if run in an ES5 runtime<\/span>\r\n<span class=\"pl-c1\">Object<\/span>.<span class=\"pl-c1\">keys<\/span>(<span style=\"color: #09885A;\">10<\/span>);<\/pre>\n<\/div>\n<p>In ECMAScript 2015, <code>Object.keys<\/code> returns <code>[]<\/code> if its argument is a primitive:<\/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 ES6 runtime<\/span>\r\n<span class=\"pl-c1\">Object<\/span>.<span class=\"pl-c1\">keys<\/span>(<span style=\"color: #09885A;\">10<\/span>);<\/pre>\n<\/div>\n<p>This is a potential source of error that wasn&#8217;t previously identified. In TypeScript 3.5, if <code>target<\/code> (or equivalently <code>lib<\/code>) is <code>ES5<\/code>, calls to <code>Object.keys<\/code> must pass a valid <code>object<\/code>.<\/p>\n<p>In general, errors here represent possible exceptions in your application and should be treated as such. If you happen to know through other means that a value is an <code>object<\/code>, a type assertion is appropriate:<\/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> fn(<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">object<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>, <span class=\"pl-v\">isArgActuallyObject<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>) {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">isArgActuallyObject<\/span>) {\r\n        <span style=\"color: #0000ff;\">const<\/span> k <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">Object<\/span>.<span class=\"pl-c1\">keys<\/span>(<span class=\"pl-smi\">arg<\/span> <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">object<\/span>);\r\n    }\r\n}<\/pre>\n<\/div>\n<p>Note that this change interacts with the change in generic inference from <code>{}<\/code> to <code>unknown<\/code>, because <code>{}<\/code> is a valid <code>object<\/code>whereas <code>unknown<\/code> isn&#8217;t:<\/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> fn&lt;<span style=\"color: #267F99;\">T<\/span>&gt;()<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>;\r\n\r\n<span style=\"color: #148A14;\">\/\/ Was okay in TypeScript 3.4, errors in 3.5 under --target ES5<\/span>\r\n<span class=\"pl-c1\">Object<\/span>.<span class=\"pl-c1\">keys<\/span>(<span class=\"pl-en\">fn<\/span>());<\/pre>\n<\/div>\n<h2 id=\"whats-next\">What&#8217;s next?<\/h2>\n<p>The final release of TypeScript 3.5 should be coming out at the end of the month. We encourage you to give the RC a try so we can ensure TypeScript 3.5 provides the ideal coding experience.<\/p>\n<p>Happy hacking!<\/p>\n<ul>\n<li>Daniel Rosenwasser and the TypeScript Team<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re happy to announce the availability of our release candidate (RC) of TypeScript 3.5. 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-2209","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.5. 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\/2209","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=2209"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2209\/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=2209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=2209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=2209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}