{"id":2862,"date":"2021-02-11T15:25:11","date_gmt":"2021-02-11T23:25:11","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=2862"},"modified":"2021-02-11T15:25:11","modified_gmt":"2021-02-11T23:25:11","slug":"announcing-typescript-4-2-rc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-2-rc\/","title":{"rendered":"Announcing TypeScript 4.2 RC"},"content":{"rendered":"<p>Today we&#8217;re excited to announce our Release Candidate of TypeScript 4.2! Between now and the stable release of TypeScript 4.2, we expect no further changes apart from critical bug fixes.<\/p>\n<p>To get started using the RC, you can get it <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild\" rel=\"nofollow\">through NuGet<\/a>, or use npm with the following command:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\">npm install 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-42rc\" 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 take a look at what&#8217;s in store for TypeScript 4.2!<\/p>\n<h2>Leading\/Middle Rest Elements in Tuple Types<\/h2>\n<p>In TypeScript, tuple types are meant to model arrays with specific lengths and element types.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\"><span style=\"color: #148a14;\">\/\/ A tuple that stores a pair of numbers<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">a<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #09885a;\">1<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #09885a;\">2<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ A tuple that stores a string, a number, and a boolean<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">b<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #09885a;\">42<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>Over time, TypeScript&#8217;s tuple types have become more and more sophisticated, since they&#8217;re also used to model things like parameter lists in JavaScript. As a result, they can have optional elements and rest elements, and can even have labels for tooling and readability.<\/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;\">\/\/ A tuple that has either one or two strings.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">c<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">string<\/span>?<span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">c<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"world\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ A labeled tuple that has either one or two strings.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">d<\/span>: <span class=\"pl-kos\">[<\/span><span class=\"pl-smi\">first<\/span>: string<span class=\"pl-kos\">,<\/span> <span class=\"pl-smi\">second<\/span>?: string<span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">d<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"world\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ A tuple with a *rest element* - holds at least 2 strings at the front,<\/span>\r\n<span style=\"color: #148a14;\">\/\/ and any number of booleans at the back.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">e<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">,<\/span> ...<span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-s1\">e<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"world\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">e<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"world\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">e<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"world\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>In TypeScript 4.2, rest elements specifically been expanded in how they can be used. In prior versions, TypeScript only allowed <code>...rest<\/code> elements at the very last position of a tuple type.<\/p>\n<p>However, now rest elements can occur <em>anywhere<\/em> within a tuple &#8211; with only a few restrictions.<\/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> <span class=\"pl-s1\">foo<\/span>: <span class=\"pl-kos\">[<\/span>...<span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-s1\">foo<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #09885a;\">123<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">foo<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #09885a;\">123<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">foo<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"hello!\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"hello!\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"hello!\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #09885a;\">123<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">bar<\/span>: <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">,<\/span> ...<span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-s1\">bar<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">bar<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"some text\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">bar<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"some\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"separated\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"text\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>The only restriction is that a rest element can be placed anywhere in a tuple, so long as it&#8217;s not followed by another optional element or rest element. In other words, only one rest element per tuple, and no optional elements after rest elements.<\/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;\">Clown<\/span> <span class=\"pl-kos\">{<\/span> <span style=\"color: #148a14;\">\/*...*\/<\/span> <span class=\"pl-kos\">}<\/span>\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Joker<\/span> <span class=\"pl-kos\">{<\/span> <span style=\"color: #148a14;\">\/*...*\/<\/span> <span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> <span style=\"color: #267f99;\">StealersWheel<\/span>: <span class=\"pl-kos\">[<\/span>...<span style=\"color: #267f99;\">Clown<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"me\"<\/span><span class=\"pl-kos\">,<\/span> ...<span style=\"color: #267f99;\">Joker<\/span><span class=\"pl-kos\">[<\/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;\">\/\/ A rest element cannot follow another rest element.<\/span>\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> <span style=\"color: #267f99;\">StringsAndMaybeBoolean<\/span>: <span class=\"pl-kos\">[<\/span>...<span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">boolean<\/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;\">\/\/ An optional element cannot follow a rest element.<\/span><\/pre>\n<\/div>\n<p>These non-trailing rest elements can be used to model functions that take any number of leading arguments, followed by a few fixed ones.<\/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> <span class=\"pl-s1\">doStuff<\/span><span class=\"pl-kos\">(<\/span>...<span class=\"pl-s1\">args<\/span>: <span class=\"pl-kos\">[<\/span>...<span class=\"pl-s1\">names<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">shouldCapitalize<\/span>: <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span>: <span class=\"pl-smi\"><span style=\"color: #0000ff;\">void<\/span><\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-en\">doStuff<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #148a14;\">\/*shouldCapitalize:*\/<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">)<\/span>\r\n<span class=\"pl-en\">doStuff<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">\"fee\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"fi\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"fo\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"fum\"<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #148a14;\">\/*shouldCapitalize:*\/<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>Even though JavaScript doesn&#8217;t have any syntax to model leading rest parameters, we were still able to declare <code>doStuff<\/code> as a function that takes leading arguments by declaring the <code>...args<\/code> rest parameter with <em>a tuple type that uses a leading rest element<\/em>. This can help model lots of existing JavaScript out there!<\/p>\n<p>For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41544\">see the original pull request<\/a>.<\/p>\n<h2>Smarter Type Alias Preservation<\/h2>\n<p>TypeScript has always used a set of heuristics for when and how to display type aliases; but these techniques often have issues beyond simple uses. For example, take the following code snippet.<\/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;\">type<\/span> <span style=\"color: #267f99;\">BasicPrimitive<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">number<\/span> | <span style=\"color: #0000ff;\">string<\/span> | <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">doStuff<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #267f99;\">BasicPrimitive<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-s1\">x<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>If we hover our mouse over <code>x<\/code> in an editor like Visual Studio, Visual Studio Code, or <a href=\"https:\/\/www.typescriptlang.org\/play?ts=4.1.3#code\/KYDwDg9gTgLgBDAnmYcBCBDAzgSwMYAKUOAtjjDgG6oC8cAdgK4kBGwUcAPnFjMfQHMucFhAgAbYBnoBuAFBzQkWHABmjengoR6cACYQAyjEarVACkoZxjYAC502fEVLkqwAJRwA3nLj+4SXgQODorG2B5ALgoYBMoXRB5AF8gA\" rel=\"nofollow\">the TypeScript Playground<\/a>, we&#8217;ll get a quick info panel that shows the type <code>BasicPrimitive<\/code>. Likewise, if we get the declaration file output (<code>.d.ts<\/code> output) for this file, TypeScript will say that <code>doStuff<\/code> returns <code>BasicPrimitive<\/code>.<\/p>\n<p>However, what happens if we return a <code>BasicPrimitive<\/code> or <code>undefined<\/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;\">export<\/span> <span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">BasicPrimitive<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">number<\/span> | <span style=\"color: #0000ff;\">string<\/span> | <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">doStuff<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #267f99;\">BasicPrimitive<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span style=\"color: #267f99;\">Math<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">random<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">&lt;<\/span> <span style=\"color: #09885a;\">0.5<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">undefined<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>We can see what happens <a href=\"https:\/\/www.typescriptlang.org\/play?ts=4.1.3#code\/KYDwDg9gTgLgBDAnmYcBCBDAzgSwMYAKUOAtjjDgG6oC8cAdgK4kBGwUcAPnFjMfQHMucFhAgAbYBnoBuALAAoRQHplcABIRqHCPTgByACYQAyjEYAzC-pHBxEAO4IIPYKgcALDPAAqyYCZ4xGDwhjhYYOIYiFhwFtAIHqhQwOZQekgoAHQqagDqqGQCHvBe1HCgKHgwwIZw5M5wYPzw2Lm5cJ2YuITEZBTl3Iz0hsAWOPS1HR0sjPBs9k5+KIHB8AAsWQBMADT18BO8UnVhEVExcG0Kqh2dTKzswrz8QtyiElJ6QyNjE1PXykUlWg8Asw2qOF0cGMZksFgAFJQMOJGMAAFzobD4IikchUYAASjgAG9FJ1yTgLHB4QBZbweLJQaTGEjwokAHjgAAYsgBWImkhTk4WdFJpPTDUbjSaGeRC4UAX0UZOFYsY6TgSJRwDlcAVQA\" rel=\"nofollow\">in the TypeScript playground<\/a>. While we might want TypeScript to display the return type of <code>doStuff<\/code> as <code>BasicPrimitive | undefined<\/code>, it instead displays <code>string | number | boolean | undefined<\/code>! What gives?<\/p>\n<p>Well this has to do with how TypeScript represents types internally. When creating a union type out of one or more union types, it will always <em>normalize<\/em> those types into a new flattened union type &#8211; but doing that loses information. The type-checker didn&#8217;t have a way to know where that <code>string | number | boolean<\/code> had come from.<\/p>\n<p>In TypeScript 4.2, our internals are a little smarter. We keep track of how types were constructed by keeping around parts of their original structures &#8211; before we normalize them. We also keep track of, and differentiate, type aliases to instances of other aliases!<\/p>\n<p>Being able to print back the types based on how you used them in your code means that as a TypeScript user, you can avoid some unfortunately humongous types getting displayed, and that often translates to getting better <code>.d.ts<\/code> file output, error messages, and in-editor type displays in quick info and signature help.<\/p>\n<p>More more information, check out <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42149\">the first pull request that improves various cases around preserving union type aliases<\/a>, along with <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42284\">a second pull request that preserves indirect aliases<\/a>.<\/p>\n<h2>Stricter Checks For The <code>in<\/code> Operator<\/h2>\n<p>In JavaScript, it is a runtime error to use a non-object type on the right side of the <code>in<\/code> operator. TypeScript 4.2 ensures this can be caught at design-time.<\/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: #a31515;\">\"foo\"<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #09885a;\">42<\/span>\r\n<span style=\"color: #148a14;\">\/\/       ~~<\/span>\r\n<span style=\"color: #148a14;\">\/\/ error! The right-hand side of an 'in' expression must not be a primitive.<\/span><\/pre>\n<\/div>\n<p>This check is fairly conservative for the most part, so if you have received an error about this, it is likely an issue in the code.<\/p>\n<p>A big thanks to our external contributor <a href=\"https:\/\/github.com\/jonhue\">Jonas H\u00fcbotter<\/a> for <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41928\">their pull request<\/a>!<\/p>\n<h2><code>--noPropertyAccessFromIndexSignature<\/code><\/h2>\n<p>Back when TypeScript first introduced index signatures, you could only get properties declared by them with &#8220;bracketed&#8221; element access syntax like <code>person[\"name\"]<\/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;\">interface<\/span> <span style=\"color: #267f99;\">SomeType<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148a14;\">\/** This is an index signature. *\/<\/span>\r\n    <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">propName<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">any<\/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\">doStuff<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #267f99;\">SomeType<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"someProperty\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>This ended up being cumbersome in situations where we need to work with objects that have arbitrary properties. For example, imagine an API where it&#8217;s common to misspell a property name by adding an extra <code>s<\/code> character at the end.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\"><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Options<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148a14;\">\/** File patterns to be excluded. *\/<\/span>\r\n    <span class=\"pl-c1\">exclude<\/span>?: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\">     * It handles any extra properties that we haven't declared as type 'any'.<\/span>\r\n<span style=\"color: #148a14;\">     *\/<\/span>\r\n    <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">x<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">any<\/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\">processOptions<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">opts<\/span>: <span style=\"color: #267f99;\">Options<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148a14;\">\/\/ Notice we're *intentionally* accessing `excludes`, not `exclude`<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">opts<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">excludes<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-smi\">console<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">error<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">\"The option `excludes` is not valid. Did you mean `exclude`?\"<\/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>To make these types of situations easier, a while back, TypeScript made it possible to use &#8220;dotted&#8221; property access syntax like <code>person.name<\/code> when a type had a string index signature. This also made it easier to transition existing JavaScript code over to TypeScript.<\/p>\n<p>However, loosening the restriction also meant that misspelling an explicitly declared property became much easier.<\/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> <span class=\"pl-en\">processOptions<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">opts<\/span>: <span style=\"color: #267f99;\">Options<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148a14;\">\/\/ ...<\/span>\r\n\r\n    <span style=\"color: #148a14;\">\/\/ Notice we're *accidentally* accessing `excludes` this time.<\/span>\r\n    <span style=\"color: #148a14;\">\/\/ Oops! Totally valid.<\/span>\r\n    <span style=\"color: #0000ff;\">for<\/span> <span class=\"pl-kos\">(<\/span><span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">excludePattern<\/span> <span style=\"color: #0000ff;\">of<\/span> <span class=\"pl-s1\">opts<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">excludes<\/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><\/pre>\n<\/div>\n<p>In some cases, users would prefer to explicitly opt into the index signature &#8211; they would prefer to get an error message when a dotted property access doesn&#8217;t correspond to a specific property declaration.<\/p>\n<p>That&#8217;s why TypeScript introduces a new flag called <code>--noPropertyAccessFromIndexSignature<\/code>. Under this mode, you&#8217;ll be opted in to TypeScript&#8217;s older behavior that issues an error. This new setting is not under the <code>strict<\/code> family of flags, since we believe users will find it more useful on certain codebases than others.<\/p>\n<p>You can understand this feature in more detail by reading up on the corresponding <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/40171\/\">pull request<\/a>. We&#8217;d also like to extend a big thanks to <a href=\"https:\/\/github.com\/Kingwl\">Wenlu Wang<\/a> who sent us this pull request!<\/p>\n<h2><code>abstract<\/code> Construct Signatures<\/h2>\n<p>TypeScript allows us to mark a class as <em>abstract<\/em>. This tells TypeScript that the class is only meant to be extended from, and that certain members need to be filled in by any subclass to actually create an instance.<\/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;\">abstract<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267f99;\">Shape<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">abstract<\/span> <span class=\"pl-c1\">getArea<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Error! Can't instantiate an abstract class.<\/span>\r\n<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267f99;\">Shape<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267f99;\">Square<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267f99;\">Shape<\/span> <span class=\"pl-kos\">{<\/span>\r\n    #<span class=\"pl-c1\">sideLength<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span class=\"pl-en\">constructor<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">sideLength<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">this<\/span><span class=\"pl-kos\">.<\/span>#<span class=\"pl-c1\">sideLength<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">sideLength<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span class=\"pl-en\">getArea<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">this<\/span><span class=\"pl-kos\">.<\/span>#<span class=\"pl-c1\">sideLength<\/span> ** <span style=\"color: #09885a;\">2<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Works fine.<\/span>\r\n<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267f99;\">Square<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #09885a;\">42<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>To make sure this restriction in <code>new<\/code>-ing up <code>abstract<\/code> classes is consistently applied, you can&#8217;t assign an <code>abstract<\/code> class to anything that expects a construct signature.<\/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;\">HasArea<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">getArea<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Error! Cannot assign an abstract constructor type to a non-abstract constructor type.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span style=\"color: #267f99;\">Ctor<\/span>: <span style=\"color: #0000ff;\">new<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span style=\"color: #267f99;\">HasArea<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #267f99;\">Shape<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>This does the right thing in case we intend to run code like <code>new Ctor<\/code>, but it&#8217;s overly-restrictive in case we want to write a subclass of <code>Ctor<\/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 class=\"pl-s1\">functon<\/span> <span class=\"pl-en\">makeSubclassWithArea<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #267f99;\">Ctor<\/span>: <span style=\"color: #0000ff;\">new<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span style=\"color: #267f99;\">HasArea<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267f99;\">Ctor<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-en\">getArea<\/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<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> <span style=\"color: #267f99;\">MyShape<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">makeSubclassWithArea<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #267f99;\">Shape<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>It also doesn&#8217;t work well with built-in helper types like <code>InstanceType<\/code>.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\"><span style=\"color: #148a14;\">\/\/ Error!<\/span>\r\n<span style=\"color: #148a14;\">\/\/ Type 'typeof Shape' does not satisfy the constraint 'new (...args: any) =&gt; any'.<\/span>\r\n<span style=\"color: #148a14;\">\/\/   Cannot assign an abstract constructor type to a non-abstract constructor type.<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">MyInstance<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #267f99;\">InstanceType<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #0000ff;\">typeof<\/span> <span style=\"color: #267f99;\">Shape<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>That&#8217;s why TypeScript 4.2 allows you to specify an <code>abstract<\/code> modifier on constructor signatures.<\/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;\">HasArea<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">getArea<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Works!<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span style=\"color: #267f99;\">Ctor<\/span>: <span class=\"pl-s1\">abstract<\/span> <span style=\"color: #0000ff;\">new<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span style=\"color: #267f99;\">HasArea<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #267f99;\">Shape<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148a14;\">\/\/        ^^^^^^^^<\/span><\/pre>\n<\/div>\n<p>Adding the <code>abstract<\/code> modifier to a construct signature signals that you can pass in <code>abstract<\/code> constructors. It doesn&#8217;t stop you from passing in other classes\/constructor functions that are &#8220;concrete&#8221; &#8211; it really just signals that there&#8217;s no intent to run the constructor directly, so it&#8217;s safe to pass in either class type.<\/p>\n<p>This feature allows us to write <em>mixin factories<\/em> in a way that supports abstract classes. For example, in the following code snippet, we&#8217;re able to use the mixin function <code>withStyles<\/code> with the <code>abstract<\/code> class <code>SuperClass<\/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;\">abstract<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267f99;\">SuperClass<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">abstract<\/span> <span class=\"pl-c1\">someMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span class=\"pl-smi\"><span style=\"color: #0000ff;\">void<\/span><\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-en\">badda<\/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\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">AbstractConstructor<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267f99;\">T<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">abstract<\/span> <span style=\"color: #0000ff;\">new<\/span> <span class=\"pl-kos\">(<\/span>...<span class=\"pl-s1\">args<\/span>: <span style=\"color: #0000ff;\">any<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span style=\"color: #267f99;\">T<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">withStyles<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267f99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267f99;\">AbstractConstructor<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #0000ff;\">object<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #267f99;\">Ctor<\/span>: <span style=\"color: #267f99;\">T<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">abstract<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267f99;\">StyledClass<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267f99;\">Ctor<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-en\">getStyles<\/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    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #267f99;\">StyledClass<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267f99;\">SubClass<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span class=\"pl-en\">withStyles<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #267f99;\">SuperClass<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\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: #0000ff;\">this<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">someMethod<\/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>Note that <code>withStyles<\/code> is demonstrating a specific rule, where a class (like <code>StyledClass<\/code>) that extends a value that&#8217;s generic and bounded by an abstract constructor (like <code>Ctor<\/code>) has to also be declared <code>abstract<\/code>. This is because there&#8217;s no way to know if a class with <em>more<\/em> abstract members was passed in, and so it&#8217;s impossible to know whether the subclass implements all the abstract members.<\/p>\n<p>You can read up more on abstract construct signatures <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/36392\">on its pull request<\/a>.<\/p>\n<h2>Understanding Your Project Structure With <code>--explainFiles<\/code><\/h2>\n<p>A surprisingly common scenario for TypeScript users is to ask &#8220;why is TypeScript including this file?&#8221;. Inferring the files of your program turns out to be a complicated process, and so there are lots of reasons why a specific combination of <code>lib.d.ts<\/code> was used, why certain files in <code>node_modules<\/code> are getting included, and why certain files are being included even though we thought specifying <code>exclude<\/code> would keep them out.<\/p>\n<p>That&#8217;s why TypeScript now provides an <code>--explainFiles<\/code> flag.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\">tsc --explainFiles<\/pre>\n<\/div>\n<p>When using this option, the TypeScript compiler will give some very verbose output about why a file ended up in your program. To read it more easily, you can forward the output to a file, or pipe it to a program that can easily view it.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\"><span style=\"color: #148a14;\"># Forward output to a text file<\/span>\r\ntsc --explainFiles <span class=\"pl-k\">&gt;<\/span> expanation.txt\r\n\r\n<span style=\"color: #148a14;\"># Pipe output to a utility program like `less`, or an editor like VS Code<\/span>\r\ntsc --explainFiles <span class=\"pl-k\">|<\/span> less\r\n\r\ntsc --explainFiles <span class=\"pl-k\">|<\/span> code -<\/pre>\n<\/div>\n<p>Typically, the output will start out by listing out reasons for including <code>lib.d.ts<\/code> files, then for local files, and then <code>node_modules<\/code> files.<\/p>\n<pre><code>TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es5.d.ts\r\n  Library referenced via 'es5' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2015.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2015.d.ts\r\n  Library referenced via 'es2015' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2016.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2016.d.ts\r\n  Library referenced via 'es2016' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2017.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2017.d.ts\r\n  Library referenced via 'es2017' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2018.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2018.d.ts\r\n  Library referenced via 'es2018' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2019.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2019.d.ts\r\n  Library referenced via 'es2019' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2020.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.es2020.d.ts\r\n  Library referenced via 'es2020' from file 'TS_Compiler_Directory\/4.2.1-rc\/lib\/lib.esnext.d.ts'\r\nTS_Compiler_Directory\/4.2.1-rc\/lib\/lib.esnext.d.ts\r\n  Library 'lib.esnext.d.ts' specified in compilerOptions\r\n\r\n... More Library References...\r\n\r\nfoo.ts\r\n  Matched by include pattern '**\/*' in 'tsconfig.json'\r\n<\/code><\/pre>\n<p>Right now, we make no guarantees about the output format &#8211; it might change over time. On that note, we&#8217;re interested in improving this format if you have any suggestions!<\/p>\n<p>For more information, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/40011\">check out the original pull request<\/a>!<\/p>\n<h2>Improved Uncalled Function Checks in Logical Expressions<\/h2>\n<p>Thanks to further improvements from <a href=\"https:\/\/github.com\/a-tarasyuk\">Alex Tarasyuk<\/a>, TypeScript&#8217;s uncalled function checks now apply within <code>&amp;&amp;<\/code> and <code>||<\/code> expressions.<\/p>\n<p>Under <code>--strictNullChecks<\/code>, the following code will now error.<\/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> <span class=\"pl-en\">shouldDisplayElement<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">element<\/span>: <span class=\"pl-smi\">Element<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">true<\/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\">getVisibleItems<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">elements<\/span>: <span class=\"pl-smi\">Element<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-s1\">elements<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">filter<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">e<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-s1\">shouldDisplayElement<\/span> <span class=\"pl-c1\">&amp;&amp;<\/span> <span class=\"pl-s1\">e<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">children<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">length<\/span><span class=\"pl-kos\">)<\/span>\r\n    <span style=\"color: #148A14;\">\/\/                          ~~~~~~~~~~~~~~~~~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ This condition will always return true since the function is always defined.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Did you mean to call it instead.<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/40197\">check out the pull request here<\/a>.<\/p>\n<h2>Relaxed Rules Between Optional Properties and String Index Signatures<\/h2>\n<p>String index signatures are a way of typing dictionary-like objects, where you want to allow access with arbitrary keys:<\/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> <span class=\"pl-s1\">movieWatchCount<\/span>: <span class=\"pl-kos\">{<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">key<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-kos\">}<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">{<\/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\">watchMovie<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">title<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span class=\"pl-s1\">movieWatchCount<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">title<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">movieWatchCount<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">title<\/span><span class=\"pl-kos\">]<\/span> ?? <span style=\"color: #09885a;\">0<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">+<\/span> <span style=\"color: #09885a;\">1<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>Of course, for any movie title not yet in the dictionary, <code>movieWatchCount[title]<\/code> will be <code>undefined<\/code> (TypeScript 4.1 added the option <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/release-notes\/typescript-4-1.html#checked-indexed-accesses---nouncheckedindexedaccess\" rel=\"nofollow\"><code>--noUncheckedIndexedAccess<\/code><\/a> to include <code>undefined<\/code> when reading from an index signature like this). Even though it&#8217;s clear that there must be some strings not present in <code>movieWatchCount<\/code>, previous versions of TypeScript treated optional object properties as unassignable to otherwise compatible index signatures, due to the presence of <code>undefined<\/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;\">WesAndersonWatchCount<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #a31515;\">\"Fantastic Mr. Fox\"<\/span>?: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n  <span style=\"color: #a31515;\">\"The Royal Tenenbaums\"<\/span>?: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n  <span style=\"color: #a31515;\">\"Moonrise Kingdom\"<\/span>?: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n  <span style=\"color: #a31515;\">\"The Grand Budapest Hotel\"<\/span>?: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">wesAndersonWatchCount<\/span>: <span style=\"color: #267f99;\">WesAndersonWatchCount<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">movieWatchCount<\/span>: <span class=\"pl-kos\">{<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">key<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-kos\">}<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">wesAndersonWatchCount<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148a14;\">\/\/    ~~~~~~~~~~~~~~~ error!<\/span>\r\n<span style=\"color: #148a14;\">\/\/ Type 'WesAndersonWatchCount' is not assignable to type '{ [key: string]: number; }'.<\/span>\r\n<span style=\"color: #148a14;\">\/\/    Property '\"Fantastic Mr. Fox\"' is incompatible with index signature.<\/span>\r\n<span style=\"color: #148a14;\">\/\/      Type 'number | undefined' is not assignable to type 'number'.<\/span>\r\n<span style=\"color: #148a14;\">\/\/        Type 'undefined' is not assignable to type 'number'. (2322)<\/span><\/pre>\n<\/div>\n<p>TypeScript 4.2 allows this assignment. However, it does <em>not<\/em> allow the assignment of non-optional properties with <code>undefined<\/code> in their types, nor does it allow writing <code>undefined<\/code> to a specific key:<\/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;\">BatmanWatchCount<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #a31515;\">\"Batman Begins\"<\/span>: <span style=\"color: #0000ff;\">number<\/span> | <span style=\"color: #0000ff;\">undefined<\/span><span class=\"pl-kos\">;<\/span>\r\n  <span style=\"color: #a31515;\">\"The Dark Knight\"<\/span>: <span style=\"color: #0000ff;\">number<\/span> | <span style=\"color: #0000ff;\">undefined<\/span><span class=\"pl-kos\">;<\/span>\r\n  <span style=\"color: #a31515;\">\"The Dark Knight Rises\"<\/span>: <span style=\"color: #0000ff;\">number<\/span> | <span style=\"color: #0000ff;\">undefined<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">batmanWatchCount<\/span>: <span style=\"color: #267f99;\">BatmanWatchCount<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Still an error in TypeScript 4.2.<\/span>\r\n<span style=\"color: #148a14;\">\/\/ `undefined` is only ignored when properties are marked optional.<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">movieWatchCount<\/span>: <span class=\"pl-kos\">{<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">key<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-kos\">}<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">batmanWatchCount<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Still an error in TypeScript 4.2.<\/span>\r\n<span style=\"color: #148a14;\">\/\/ Index signatures don't implicitly allow explicit `undefined`.<\/span>\r\n<span class=\"pl-s1\">movieWatchCount<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"It's the Great Pumpkin, Charlie Brown\"<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">undefined<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>The new rule also does not apply to number index signatures, since they are assumed to be array-like and dense:<\/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;\">let<\/span> <span class=\"pl-s1\">sortOfArrayish<\/span>: <span class=\"pl-kos\">{<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">key<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">numberKeys<\/span>: <span class=\"pl-kos\">{<\/span> <span style=\"color: #09885a;\">42<\/span>?: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Error! Type '{ 42?: string | undefined; }' is not assignable to type '{ [key: number]: string; }'.<\/span>\r\n<span class=\"pl-s1\">sortOfArrayish<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">numberKeys<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>You can get a better sense of this change <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41921\">by reading up on the original PR<\/a>.<\/p>\n<h2>Declare Missing Helper Function<\/h2>\n<p>Thanks to <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41215\">a community pull request<\/a> from <a href=\"https:\/\/github.com\/a-tarasyuk\">Alexander Tarasyuk<\/a>, we now have a quick fix for declaring new functions and methods based on the call-site!<\/p>\n<p><img decoding=\"async\" alt=\"An un-declared function foo being called, with a quick fix scaffolding out the new contents of the file\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2021\/01\/addMissingFunction-4.2.gif\" \/><\/p>\n<h2>Breaking Changes<\/h2>\n<p>We always strive to minimize breaking changes in a release. TypeScript 4.2 contains some breaking changes, but we believe they should be manageable in an upgrade.<\/p>\n<h3><code>lib.d.ts<\/code> Updates<\/h3>\n<p>As with every TypeScript version, declarations for <code>lib.d.ts<\/code> (especially the declarations generated for web contexts), have changed. There are various changes, though <code>Intl<\/code> and <code>ResizeObserver<\/code> are may have changes that end up being the most disruptive.`<\/p>\n<h3><code>noImplicitAny<\/code> Errors Apply to Loose <code>yield<\/code> Expressions<\/h3>\n<p>When a <code>yield<\/code> expression is captured, but isn&#8217;t contextually typed (i.e. TypeScript can&#8217;t figure out what the type is), TypeScript will now issue an implicit <code>any<\/code> error.<\/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>* <span class=\"pl-s1\">g1<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">value<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">yield<\/span> <span style=\"color: #09885a;\">1<\/span><span class=\"pl-kos\">;<\/span> <span style=\"color: #148a14;\">\/\/ report implicit any error<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span>* <span class=\"pl-s1\">g2<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #0000ff;\">yield<\/span> <span style=\"color: #09885a;\">1<\/span><span class=\"pl-kos\">;<\/span> <span style=\"color: #148a14;\">\/\/ result is unused, no error<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span>* <span class=\"pl-s1\">g3<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">value<\/span>: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">yield<\/span> <span style=\"color: #09885a;\">1<\/span><span class=\"pl-kos\">;<\/span> <span style=\"color: #148a14;\">\/\/ result is contextually typed by type annotation of `value`, no error.<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span>* <span class=\"pl-s1\">g3<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #267f99;\">Generator<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-smi\"><span style=\"color: #0000ff;\">void<\/span><\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">value<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">yield<\/span> <span style=\"color: #09885a;\">1<\/span><span class=\"pl-kos\">;<\/span> <span style=\"color: #148a14;\">\/\/ result is contextually typed by return-type annotation of `g3`, no error.<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>See more details in <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41348\">the corresponding changes<\/a>.<\/p>\n<h3><a id=\"user-content-expanded-uncalled-function-checks\" class=\"anchor\" href=\"https:\/\/github.com\/microsoft\/TypeScript-Blog-Posts\/blob\/master\/posts\/TypeScript%204.2\/RC\/Post.md#expanded-uncalled-function-checks\" aria-hidden=\"true\"><\/a>Expanded Uncalled Function Checks<\/h3>\n<p>As described above, uncalled function checks will now operate consistently within <code>&amp;&amp;<\/code> and <code>||<\/code> expressions when using <code>--strictNullChecks<\/code>. This can be a source of new breaks, but is typically an indication of a logic error in existing code.<\/p>\n<h3>Type Arguments in JavaScript Are Not Parsed as Type Arguments<\/h3>\n<p>Type arguments were already not allowed in JavaScript, but in TypeScript 4.2, the parser will parse them in a more spec-compliant way. So when writing the following code in a JavaScript file:<\/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-en\">f<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #267f99;\">T<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #09885a;\">100<\/span><span class=\"pl-kos\">)<\/span><\/pre>\n<\/div>\n<p>TypeScript will parse it as the following JavaScript:<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0; padding: 10px; border-radius: 10px;\"><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">f<\/span> <span class=\"pl-c1\">&lt;<\/span> <span class=\"pl-v\">T<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-kos\">(<\/span><span style=\"color: #09885a;\">100<\/span><span class=\"pl-kos\">)<\/span><\/pre>\n<\/div>\n<p>This may impact you if you were leveraging TypeScript&#8217;s API to parse type constructs in JavaScript files, which may have occurred when trying to parse Flow files.<\/p>\n<h2>The <code>in<\/code> Operator No Longer Allows Primitive Types on the Right Side<\/h2>\n<p>As mentioned, it is an error to use a primitive on the right side of an <code>in<\/code> operator, and TypeScript 4.2 is stricter about this sort of 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: #a31515;\">\"foo\"<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #09885a;\">42<\/span>\r\n<span style=\"color: #148a14;\">\/\/       ~~<\/span>\r\n<span style=\"color: #148a14;\">\/\/ error! The right-hand side of an 'in' expression must not be a primitive.<\/span><\/pre>\n<\/div>\n<p>See <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41928\">the pull request<\/a> for more details on what&#8217;s checked.<\/p>\n<h2>Subtype Reduction May Reduce <code>undefined | void<\/code> To <code>void<\/code> More Aggressively<\/h2>\n<p>TypeScript 4.2 brings an optimization that can improve situations with very large union types of literal types. Part of this change involves reducing the number of literals in a type before doing a more-costly reduction across a union type.<\/p>\n<p>But this reduction can lead to an observable differences in inference, which may cause breaks in existing code that intermingles <code>void<\/code> and <code>undefined<\/code> in union types. As a work-around, we recommend carefully reconsidering whether you really meant to write <code>void<\/code> (an opaque return type for values that shouldn&#8217;t be re-used at all) or <code>undefined<\/code>.<\/p>\n<p>For more information, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42353\">see the original pull request<\/a>.<\/p>\n<h2>Tuple size limits for spreads<\/h2>\n<p>Tuple types can be made by using any sort of spread syntax (<code>...<\/code>) in TypeScript.<\/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;\">\/\/ Tuple types with spread elements<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">NumStr<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">NumStrNumStr<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span>...<span style=\"color: #267f99;\">NumStr<\/span><span class=\"pl-kos\">,<\/span> ...<span style=\"color: #267f99;\">NumStr<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ Array spread expressions<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">numStr<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span><span style=\"color: #09885a;\">123<\/span><span class=\"pl-kos\">,<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">]<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">numStrNumStr<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-kos\">[<\/span>...<span class=\"pl-s1\">numStr<\/span><span class=\"pl-kos\">,<\/span> ...<span class=\"pl-s1\">numStr<\/span><span class=\"pl-kos\">]<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>Sometimes these tuple types can accidentally grow to be huge, and that can make type-checking take a long time. Instead of letting the type-checking process hang (which is especially bad in editor scenarios), TypeScript has a limiter in place to avoid doing all that work.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42448\">see this pull request<\/a> for more details.<\/p>\n<h2><code>.d.ts<\/code> Extensions Cannot Be Used In Import Paths<\/h2>\n<p>In TypeScript 4.2, it is now an error for your import paths to contain <code>.d.ts<\/code> in the extension.<\/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;\">\/\/ must be changed something like<\/span>\r\n<span style=\"color: #148a14;\">\/\/   - \".\/foo\"<\/span>\r\n<span style=\"color: #148a14;\">\/\/   - \".\/foo.js\"<\/span>\r\n<span style=\"color: #0000ff;\">import<\/span> <span class=\"pl-kos\">{<\/span> <span style=\"color: #267f99;\">Foo<\/span> <span class=\"pl-kos\">}<\/span> <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\">\".\/foo.d.ts\"<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>Instead, your import paths should reflect whatever your loader will do at runtime. Any of the following imports might be usable instead.<\/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;\">import<\/span> <span class=\"pl-kos\">{<\/span> <span style=\"color: #267f99;\">Foo<\/span> <span class=\"pl-kos\">}<\/span> <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\">\".\/foo\"<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">import<\/span> <span class=\"pl-kos\">{<\/span> <span style=\"color: #267f99;\">Foo<\/span> <span class=\"pl-kos\">}<\/span> <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\">\".\/foo.js\"<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">import<\/span> <span class=\"pl-kos\">{<\/span> <span style=\"color: #267f99;\">Foo<\/span> <span class=\"pl-kos\">}<\/span> <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\">\".\/foo\/index.js\"<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<h2>Reverting Template Literal Inference<\/h2>\n<p>This change removed a feature from TypeScript 4.2 beta. If you haven&#8217;t yet upgraded past our last stable release, you won&#8217;t be affected, but you may still be interested in the change.<\/p>\n<p>The beta version of TypeScript 4.2 included a change in inference to template strings. In this change, template string literals would either be given template string types or simplify to multiple string literal types. These types would then <em>widen<\/em> to <code>string<\/code> when assigning to mutable variables.<\/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;\">const<\/span> <span class=\"pl-s1\">yourName<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ 'bar' is constant.<\/span>\r\n<span style=\"color: #148a14;\">\/\/ It has type '`hello ${string}`'.<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">bar<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>yourName<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n\r\n<span style=\"color: #148a14;\">\/\/ 'baz' is mutable.<\/span>\r\n<span style=\"color: #148a14;\">\/\/ It has type 'string'.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">baz<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>yourName<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>This is similar to how string literal inference works.<\/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;\">\/\/ 'bar' has type '\"hello\"'.<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">bar<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ 'baz' has type 'string'.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">baz<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>For that reason, we believed that making template string expressions have template string types would be &#8220;consistent&#8221;; however, from what we&#8217;ve seen and heard, that isn&#8217;t always desirable.<\/p>\n<p>In response, we&#8217;ve reverted this feature (and potential breaking change). If you <em>do<\/em> want a template string expression to be given a literal-like type, you can always add <code>as const<\/code> to the end of it.<\/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;\">const<\/span> <span class=\"pl-s1\">yourName<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ 'bar' has type '`hello ${string}`'.<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">bar<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>yourName<span class=\"pl-kos\">}<\/span><\/span>`<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148a14;\">\/\/                              ^^^^^^^^<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/\/ 'baz' has type 'string'.<\/span>\r\n<span style=\"color: #0000ff;\">const<\/span> <span class=\"pl-s1\">baz<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>yourName<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<h2>TypeScript&#8217;s <code>lift<\/code> Callback in <code>visitNode<\/code> Uses a Different Type<\/h2>\n<p>TypeScript has a <code>visitNode<\/code> function that takes a <code>lift<\/code> function. <code>lift<\/code> now expects a <code>readonly Node[]<\/code> instead of a <code>NodeArray&lt;Node&gt;<\/code>. This is technically an API breaking change which you can read more on <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42000\">here<\/a>.<\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>If you can&#8217;t wait to hear about what comes after TypeScript 4.2, you&#8217;re in luck &#8211; you can now <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/42762\">take a look at the TypeScript 4.3 iteration plan<\/a> and our <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">rolling feature roadmap<\/a>.<\/p>\n<p>But coming back to 4.2, as we inch closer to our stable release over the next 2 weeks, it&#8217;s crucial that we stamp out any issues to make sure it&#8217;s easy for everyone to adopt. We&#8217;re counting on your feedback to help make this an excellent release, so try it today, and <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\">let us know if you run into anything<\/a>!<\/p>\n<p>Happy Hacking!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re excited to announce our Release Candidate of TypeScript 4.2! Between now and the stable release of TypeScript 4.2, we expect no further changes apart from critical bug fixes. To get started using the RC, you can get it through NuGet, or use npm with the following command: npm install typescript@rc You can also [&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-2862","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Today we&#8217;re excited to announce our Release Candidate of TypeScript 4.2! Between now and the stable release of TypeScript 4.2, we expect no further changes apart from critical bug fixes. To get started using the RC, you can get it through NuGet, or use npm with the following command: npm install typescript@rc You can also [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2862","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=2862"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2862\/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=2862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=2862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=2862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}