{"id":3259,"date":"2022-01-21T15:07:52","date_gmt":"2022-01-21T23:07:52","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=3259"},"modified":"2022-01-21T15:07:52","modified_gmt":"2022-01-21T23:07:52","slug":"announcing-typescript-4-6-beta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-6-beta\/","title":{"rendered":"Announcing TypeScript 4.6 Beta"},"content":{"rendered":"<p>Today we are excited to announce the beta release of TypeScript 4.6!<\/p>\n<p>To get started using the beta, you can get it\u00a0<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 position-relative overflow-auto\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\">npm install typescript@beta<\/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-46beta\" rel=\"nofollow\">Downloading for Visual Studio 2019\/2017<\/a><\/li>\n<li>Following directions for\u00a0<a href=\"https:\/\/code.visualstudio.com\/Docs\/languages\/typescript#_using-newer-typescript-versions\" rel=\"nofollow\">Visual Studio Code<\/a>\u00a0and\u00a0<a href=\"https:\/\/github.com\/Microsoft\/TypeScript-Sublime-Plugin\/#note-using-different-versions-of-typescript\">Sublime Text 3<\/a>.<\/li>\n<\/ul>\n<p>Here&#8217;s a quick list of what&#8217;s new in TypeScript 4.6!<\/p>\n<ul>\n<li><a href=\"#code-before-super\">Allowing Code in Constructors Before\u00a0<code>super()<\/code><\/a><\/li>\n<li><a href=\"#improved-depth-checks\">Improved Recursion Depth Checks<\/a><\/li>\n<li><a href=\"#indexed-access-inference-improvements\">Indexed Access Inference Improvements<\/a><\/li>\n<li><a href=\"#dependent-parameters-cfa\">Control Flow Analysis for Dependent Parameters<\/a><\/li>\n<li><a href=\"#syntax-errors-js\">More Syntax and Binding Errors in JavaScript<\/a><\/li>\n<li><a href=\"#typescript-trace-analyzer\">TypeScript Trace Analyzer<\/a><\/li>\n<li><a href=\"#breaking-changes\">Breaking Changes<\/a><\/li>\n<\/ul>\n<h2><a name=\"code-before-super\"><\/a>Allowing Code in Constructors Before\u00a0<code>super()<\/code><\/h2>\n<p>In JavaScript classes it&#8217;s mandatory to call\u00a0<code>super()<\/code>\u00a0before referring to\u00a0<code>this<\/code>. TypeScript enforces this as well, though it was a bit too strict in\u00a0<em>how<\/em>\u00a0it ensured this. In TypeScript, it was previously an error to contain\u00a0<em>any<\/em>\u00a0code at the beginning of a constructor if its containing class had any property initializers.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">Base<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Derived<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267F99;\">Base<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">someProperty<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span class=\"pl-en\">constructor<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ have to call 'super()' first because it needs to initialize 'someProperty'.<\/span>\r\n        <span class=\"pl-en\">doSomeStuff<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-smi\">super<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>This made it cheap to check that\u00a0<code>super()<\/code>\u00a0got called before\u00a0<code>this<\/code>\u00a0was referenced, but this ends up rejecting a lot of valid code. TypeScript 4.6 is now much more lenient in that check and permits other code to run before\u00a0<code>super()<\/code>., all while still ensuring that\u00a0<code>super()<\/code>\u00a0occurs at the top-level before any references to\u00a0<code>this<\/code>.<\/p>\n<p>We&#8217;d like to extend our thanks to\u00a0<a href=\"https:\/\/github.com\/JoshuaKGoldberg\">Joshua Goldberg<\/a>\u00a0for\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/29374\">patiently working with us to land this change<\/a>!<\/p>\n<h2><a name=\"improved-depth-checks\"><\/a>Improved Recursion Depth Checks<\/h2>\n<p>TypeScript has some interesting challenges due to the fact that it&#8217;s built on a structural type system that also provides generics.<\/p>\n<p>In a structural type system, object types are compatible based on the members they have.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">Source<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">prop<\/span>: <span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">Target<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">prop<\/span>: <span class=\"pl-smi\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">check<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">source<\/span>: <span style=\"color: #267F99;\">Source<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">target<\/span>: <span style=\"color: #267F99;\">Target<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-s1\">target<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">source<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Type 'Source' is not assignable to type 'Target'.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/   Types of property 'prop' are incompatible.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/     Type 'string' is not assignable to type 'number'.<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>Notice that whether or not\u00a0<code>Source<\/code>\u00a0is compatible with\u00a0<code>Target<\/code>\u00a0has to do with whether their\u00a0<em>properties<\/em>\u00a0are assignable. In this case, that&#8217;s just\u00a0<code>prop<\/code>.<\/p>\n<p>When you introduce generics into this, there are some harder questions to answer. For instance, is a\u00a0<code>Source&lt;string&gt;<\/code>\u00a0assignable to a\u00a0<code>Target&lt;number&gt;<\/code>\u00a0in the following case?<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">Source<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">prop<\/span>: <span style=\"color: #267F99;\">Source<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Source<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">Target<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">prop<\/span>: <span style=\"color: #267F99;\">Target<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Target<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">check<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">source<\/span>: <span style=\"color: #267F99;\">Source<\/span><span class=\"pl-kos\">&lt;<\/span><span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">target<\/span>: <span style=\"color: #267F99;\">Target<\/span><span class=\"pl-kos\">&lt;<\/span><span class=\"pl-smi\">number<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-s1\">target<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">source<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>In order to answer that, TypeScript needs to check whether the types of\u00a0<code>prop<\/code>\u00a0are compatible. That leads to the another question: is a\u00a0<code>Source&lt;Source&lt;string&gt;&gt;<\/code>\u00a0assignable to a\u00a0<code>Target&lt;Target&lt;number&gt;&gt;<\/code>? To answer that, TypeScript checks whether\u00a0<code>prop<\/code>\u00a0is compatible for\u00a0<em>those<\/em>\u00a0types, and ends up checking whether\u00a0<code>Source&lt;Source&lt;Source&lt;string&gt;&gt;&gt;<\/code>\u00a0is assignable to\u00a0<code>Target&lt;Target&lt;Target&lt;number&gt;&gt;&gt;<\/code>. Keep going for a bit, and you might notice that the type infinitely expands the more you dig in.<\/p>\n<p>TypeScript has a few heuristics here &#8211; if a type\u00a0<em>appears<\/em>\u00a0to be infinitely expanding after encountering a certain depth check, then it considers that the types\u00a0<em>could<\/em>\u00a0be compatible. This is usually enough, but embarrassingly there were some false-negatives that this wouldn&#8217;t catch.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">prop<\/span>: <span style=\"color: #267F99;\">T<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x<\/span>: <span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">y<\/span>: <span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">&lt;<\/span><span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">y<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>A human reader can see that\u00a0<code>x<\/code>\u00a0and\u00a0<code>y<\/code>\u00a0should be incompatible in the above example. While the types are deeply nested, that&#8217;s just a consequence of how they were declared. The heuristic was meant to capture cases where deeply-nested types were generated through exploring the types, not from when a developer wrote that type out themselves.<\/p>\n<p>TypeScript 4.6 is now able to distinguish these cases, and correctly errors on the last example. Additionally, because the language is no longer concerned with false-positives from explicitly-written types, TypeScript can conclude that a type is infinitely expanding much earlier, and save a bunch of work in checking for type compatibility. As a result, libraries on DefinitelyTyped like\u00a0<code>redux-immutable<\/code>,\u00a0<code>react-lazylog<\/code>, and\u00a0<code>yup<\/code>\u00a0saw a 50% reduction in check-time.<\/p>\n<p>You may already have this change because it was cherry-picked into TypeScript 4.5.3, but it is a notable feature of TypeScript 4.6 which you can read up more about\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/46599\">here<\/a>.<\/p>\n<h2><a name=\"indexed-access-inference-improvements\"><\/a>Indexed Access Inference Improvements<\/h2>\n<p>TypeScript now can correctly infer to indexed access types which immediately index into a mapped object type.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">TypeMap<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #a31515;\">\"number\"<\/span>: <span class=\"pl-smi\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #a31515;\">\"string\"<\/span>: <span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #a31515;\">\"boolean\"<\/span>: <span class=\"pl-smi\">boolean<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">UnionRecord<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">P<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">TypeMap<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">{<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #267F99;\">P<\/span><span class=\"pl-kos\">]<\/span>:\r\n    <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-c1\">kind<\/span>: <span style=\"color: #267F99;\">K<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-c1\">v<\/span>: <span style=\"color: #267F99;\">TypeMap<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #267F99;\">K<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-c1\">f<\/span>: <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">p<\/span>: <span style=\"color: #267F99;\">TypeMap<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #267F99;\">K<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-smi\"><span style=\"color: #0000ff;\">void<\/span><\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #267F99;\">P<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">processRecord<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">K<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267F99;\">TypeMap<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">record<\/span>: <span style=\"color: #267F99;\">UnionRecord<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267F99;\">K<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-s1\">record<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">f<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">record<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">v<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span class=\"pl-en\">processRecord<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">kind<\/span>: <span style=\"color: #a31515;\">\"string\"<\/span><span class=\"pl-kos\">,<\/span>\r\n    <span class=\"pl-c1\">v<\/span>: <span style=\"color: #a31515;\">\"hello!\"<\/span><span class=\"pl-kos\">,<\/span>\r\n\r\n    <span style=\"color: #148A14;\">\/\/ 'val' used to implicitly have the type 'string | number | boolean',<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ but now is correctly inferred to just 'string'.<\/span>\r\n    <span class=\"pl-en\">f<\/span>: <span class=\"pl-s1\">val<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-smi\">console<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">log<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">val<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">toUpperCase<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">)<\/span><\/pre>\n<\/div>\n<p>This pattern was already supported and allowed TypeScript to understand that the call to\u00a0<code>record.f(record.v)<\/code>\u00a0is valid, but previously the call to\u00a0<code>processRecord<\/code>\u00a0would give poor inference results for\u00a0<code>val<\/code><\/p>\n<p>TypeScript 4.6 improves this so that no type assertions are necessary within the call to\u00a0<code>processRecord<\/code>.<\/p>\n<p>For more information, you can\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47109\">read up on the pull request<\/a>.<\/p>\n<h2><a name=\"dependent-parameters-cfa\"><\/a>Control Flow Analysis for Dependent Parameters<\/h2>\n<p>A signature can be declared with a rest parameter whose type is a discriminated union of tuples.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">func<\/span><span class=\"pl-kos\">(<\/span>...<span class=\"pl-s1\">args<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"str\"<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">|<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"num\"<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-smi\">number<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>What this says is that when the first argument is the string\u00a0<code>\"str\"<\/code>, then its second argument is a\u00a0<code>string<\/code>, and when its first argument is the string\u00a0<code>\"num\"<\/code>, its second argument is a\u00a0<code>number<\/code>.<\/p>\n<p>In cases where TypeScript infers from a signature with this kind of rest parameter, TypeScript can now narrow parameters that depend on others.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">Func<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">(<\/span>...<span class=\"pl-s1\">args<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"a\"<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-smi\">number<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">|<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"b\"<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-smi\"><span style=\"color: #0000ff;\">void<\/span><\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-en\">f1<\/span>: <span style=\"color: #267F99;\">Func<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">kind<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">payload<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">kind<\/span> <span class=\"pl-c1\">===<\/span> <span style=\"color: #a31515;\">\"a\"<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-s1\">payload<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">toFixed<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>  <span style=\"color: #148A14;\">\/\/ 'payload' narrowed to 'number'<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">kind<\/span> <span class=\"pl-c1\">===<\/span> <span style=\"color: #a31515;\">\"b\"<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-s1\">payload<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">toUpperCase<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>  <span style=\"color: #148A14;\">\/\/ 'payload' narrowed to 'string'<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-en\">f1<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">\"a\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #09885A;\">42<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">f1<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">\"b\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>For more information,\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47190\">see the change on GitHub<\/a>.<\/p>\n<h2><a name=\"syntax-errors-js\"><\/a>More Syntax and Binding Errors in JavaScript<\/h2>\n<p>TypeScript has expanded its set of syntax and binding errors in JavaScript files. You&#8217;ll see these new errors if you open JavaScript files in an editor like Visual Studio or Visual Studio Code, or if you run JavaScript code through the TypeScript compiler &#8211; even if you don&#8217;t turn on\u00a0<code>checkJs<\/code>\u00a0or add a\u00a0<code>\/\/ @ts-check<\/code>\u00a0comment to the top of your files.<\/p>\n<p>As one example, if you have two declarations of a\u00a0<code>const<\/code>\u00a0in the same scope of a JavaScript file, TypeScript will now issue an error on those declarations.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">foo<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">1234<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148A14;\">\/\/    ~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error: Cannot redeclare block-scoped variable 'foo'.<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">foo<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">5678<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148A14;\">\/\/    ~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error: Cannot redeclare block-scoped variable 'foo'.<\/span><\/pre>\n<\/div>\n<p>As another example, TypeScript will let you know if a modifier is being incorrectly used.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">container<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n<span style=\"color: #148A14;\">\/\/  ~~~~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error: Modifiers cannot appear here.<\/span>\r\n\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>These errors can be disabled by adding a\u00a0<code>\/\/ @ts-nocheck<\/code>\u00a0at the top of your file, but we&#8217;re interested in hearing some early feedback about how it works for your JavaScript workflow. You can easily try it out for Visual Studio Code by installing the\u00a0<a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-vscode.vscode-typescript-next\" rel=\"nofollow\">TypeScript and JavaScript Nightly Extension<\/a>, and read up more on the\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47067\">first<\/a>\u00a0and\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47075\">second<\/a>\u00a0pull requests.<\/p>\n<h2><a name=\"typescript-trace-analyzer\"><\/a>TypeScript Trace Analyzer<\/h2>\n<p>Occasionally, teams may encounter types that are computationally expensive to create and compare.\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/wiki\/Performance#performance-tracing\">TypeScript has a\u00a0<code>--generateTrace<\/code>\u00a0flag<\/a>\u00a0to help identify some of those expensive types, or sometimes help diagnose issues in the TypeScript compiler. While the information generated by\u00a0<code>--generateTrace<\/code>\u00a0can be useful (especially with some information added in TypeScript 4.6), it can often be hard to read in existing trace visualizers.<\/p>\n<p>We recently published a tool called\u00a0<a href=\"https:\/\/www.npmjs.com\/package\/@typescript\/analyze-trace\" rel=\"nofollow\">@typescript\/analyze-trace<\/a>\u00a0to get a more digestible view of this information. While we don&#8217;t expect everyone to need\u00a0<code>analyze-trace<\/code>, we think it can come in handy for any team that is running into\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/wiki\/Performance\">build performance issues with TypeScript<\/a>.<\/p>\n<p>For more information,\u00a0<a href=\"https:\/\/github.com\/microsoft\/typescript-analyze-trace\">see the\u00a0<code>analyze-trace<\/code>\u00a0tool&#8217;s repo<\/a>.<\/p>\n<h2><a name=\"breaking-changes\"><\/a>Breaking Changes<\/h2>\n<h3>Object Rests Drop Unspreadable Members from Generic Objects<\/h3>\n<p>Object rest expressions now drop members that appear to be unspreadable on generic objects. In the following example&#8230;<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">someProperty<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">42<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span class=\"pl-en\">someMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267F99;\">Thing<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">x<\/span>: <span style=\"color: #267F99;\">T<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-kos\">{<\/span> someProperty<span class=\"pl-kos\">,<\/span> ...<span class=\"pl-s1\">rest<\/span> <span class=\"pl-kos\">}<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">x<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span style=\"color: #148A14;\">\/\/ Used to work, is now an error!<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Property 'someMethod' does not exist on type 'Omit&lt;T, \"someProperty\" | \"someMethod\"&gt;'.<\/span>\r\n    <span class=\"pl-s1\">rest<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">someMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>the variable\u00a0<code>rest<\/code>\u00a0used to have the type\u00a0<code>Omit&lt;T, \"someProperty\"&gt;<\/code>\u00a0because TypeScript would strictly analyze which other properties were destructured. This doesn&#8217;t model how\u00a0<code>...rest<\/code>\u00a0would work in a destructuring from a non-generic type because\u00a0<code>someMethod<\/code>\u00a0would typically be dropped as well. In TypeScript 4.6, the type of\u00a0<code>rest<\/code>\u00a0is\u00a0<code>Omit&lt;T, \"someProperty\" | \"someMethod\"&gt;<\/code>.<\/p>\n<p>This can also come up in cases when destructuring from\u00a0<code>this<\/code>. When destructuring\u00a0<code>this<\/code>\u00a0using a\u00a0<code>...rest<\/code>\u00a0element, unspreadable and non-public members are now dropped, which is consistent with destructuring instances of a class in other places.<\/p>\n<div class=\"highlight highlight-source-ts position-relative overflow-auto\">\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;\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">someProperty<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">42<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span class=\"pl-en\">someMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span class=\"pl-en\">someOtherMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-kos\">{<\/span> someProperty<span class=\"pl-kos\">,<\/span> ...<span class=\"pl-s1\">rest<\/span> <span class=\"pl-kos\">}<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-smi\">this<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n        <span style=\"color: #148A14;\">\/\/ Used to work, is now an error!<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ Property 'someMethod' does not exist on type 'Omit&lt;T, \"someProperty\" | \"someMethod\"&gt;'.<\/span>\r\n        <span class=\"pl-s1\">rest<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">someMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>For more details,\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47078\">see the corresponding change here<\/a>.<\/p>\n<h3>JavaScript Files Always Receive Grammar and Binding Errors<\/h3>\n<p>Previously, TypeScript would ignore most grammar errors in JavaScript apart from accidentally using TypeScript syntax in a JavaScript file. TypeScript now shows JavaScript syntax and binding errors in your file, such as using incorrect modifiers, duplicate declarations, and more. These will typically be most apparent in Visual Studio Code or Visual Studio, but can also occur when running JavaScript code through the TypeScript compiler.<\/p>\n<p>You can explicitly turn these errors off by inserting a\u00a0<code>\/\/ @ts-nocheck<\/code>\u00a0comment at the top of your file.<\/p>\n<p>For more information, see the\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47067\">first<\/a>\u00a0and\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47075\">second<\/a>\u00a0implementing pull requests for these features.<\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>Over the next few weeks, we&#8217;ll be hard at work addressing any issues you encounter with the beta release, and bringing those changes in for a release candidate. For some details including target release dates, you can take a look at\u00a0<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/46858\">the iteration plan for TypeScript 4.6<\/a>.<\/p>\n<p>We hope you give this beta a shot and let us know what you think!<\/p>\n<p>Happy Hacking!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we are excited to announce the beta release of TypeScript 4.6! To get started using the beta, you can get it\u00a0through NuGet, or use npm with the following command: npm install typescript@beta You can also get editor support by Downloading for Visual Studio 2019\/2017 Following directions for\u00a0Visual Studio Code\u00a0and\u00a0Sublime Text 3. Here&#8217;s a quick [&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-3259","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Today we are excited to announce the beta release of TypeScript 4.6! To get started using the beta, you can get it\u00a0through NuGet, or use npm with the following command: npm install typescript@beta You can also get editor support by Downloading for Visual Studio 2019\/2017 Following directions for\u00a0Visual Studio Code\u00a0and\u00a0Sublime Text 3. Here&#8217;s a quick [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3259","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=3259"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3259\/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=3259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=3259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=3259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}