{"id":2934,"date":"2021-04-01T12:21:04","date_gmt":"2021-04-01T20:21:04","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=2934"},"modified":"2021-04-05T11:12:58","modified_gmt":"2021-04-05T19:12:58","slug":"announcing-typescript-4-3-beta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-3-beta\/","title":{"rendered":"Announcing TypeScript 4.3 Beta"},"content":{"rendered":"<p>Today we&#8217;re excited to announce our Beta of TypeScript 4.3!<\/p>\n<p>To get started using the beta, 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@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-43beta\" 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 dive in to what TypeScript 4.3 brings!<\/p>\n<h2>Separate Write Types on Properties<\/h2>\n<p>In JavaScript, it&#8217;s pretty common for APIs to convert values that are passed in before storing them. This often happens with getters and setters too. For example, let&#8217;s imagine we&#8217;ve got a class with a setter that always converts a value into a <code>number<\/code> before saving it in a private field.<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span class=\"pl-v\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    #<span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">;<\/span>\r\n    \r\n    <span style=\"color: #0000ff;\">get<\/span> <span class=\"pl-en\">size<\/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\">size<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n    <span style=\"color: #0000ff;\">set<\/span> <span class=\"pl-en\">size<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">num<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-v\">Number<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n        <span style=\"color: #148A14;\">\/\/ Don't allow NaN and stuff.<\/span>\r\n        <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-c1\">!<\/span><span class=\"pl-v\">Number<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">isFinite<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">num<\/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-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">;<\/span>\r\n            <span style=\"color: #0000ff;\">return<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-kos\">}<\/span>\r\n\r\n        <span style=\"color: #0000ff;\">this<\/span><span class=\"pl-kos\">.<\/span>#<span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">num<\/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>How would we type this JavaScript code in TypeScript? Well, technically we don&#8217;t have to do anything special here &#8211; TypeScript can look at this with no explicit types and can figure out that <code>size<\/code> is a number.<\/p>\n<p>The problem is that <code>size<\/code> allows you to assign more than just <code>number<\/code>s to it. We could get around this by saying that <code>size<\/code> has the type <code>unknown<\/code> or <code>any<\/code> like in this 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;\">class<\/span> <span style=\"color: #267F99;\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n    <span style=\"color: #0000ff;\">get<\/span> <span class=\"pl-en\">size<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #0000ff;\">unknown<\/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\">size<\/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>But that&#8217;s no good &#8211; <code>unknown<\/code> forces people reading <code>size<\/code> to do a type assertion, and <code>any<\/code> won&#8217;t catch any mistakes. If we really want to model APIs that convert values, previous versions of TypeScript forced us to pick between being precise (which makes reading values easier, and writing harder) and being permissive (which makes writing values easier, and reading harder).<\/p>\n<p>That&#8217;s why TypeScript 4.3 allows you to specify types for reading and writing to properties.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    #<span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">get<\/span> <span class=\"pl-en\">size<\/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 style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">this<\/span><span class=\"pl-kos\">.<\/span>#<span class=\"pl-c1\">size<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">set<\/span> <span class=\"pl-en\">size<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">num<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #267F99;\">Number<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n        <span style=\"color: #148A14;\">\/\/ Don't allow NaN and stuff.<\/span>\r\n        <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-c1\">!<\/span><span style=\"color: #267F99;\">Number<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">isFinite<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">num<\/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-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">;<\/span>\r\n            <span style=\"color: #0000ff;\">return<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-kos\">}<\/span>\r\n\r\n        <span style=\"color: #0000ff;\">this<\/span><span class=\"pl-kos\">.<\/span>#<span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">num<\/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>In the above example, our <code>set<\/code> accessor takes a broader set of types (<code>string<\/code>s, <code>boolean<\/code>s, and <code>number<\/code>s), but our <code>get<\/code> accessor always guarantees it will be a <code>number<\/code>. Now we can finally assign other types to these properties with no errors!<\/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\">thing<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Thing<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Assigning other types to `thing.size` works!<\/span>\r\n<span class=\"pl-s1\">thing<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">thing<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">thing<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">42<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Reading `thing.size` always produces a number!<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">mySize<\/span>: <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">thing<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-c1\">size<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>When considering how two properties with the same name relate to each other, TypeScript will only use the &#8220;reading&#8221; type (e.g. the type on the <code>get<\/code> accessor above). &#8220;Writing&#8221; types are only considered when directly writing to a property.<\/p>\n<p>Keep in mind, this isn&#8217;t a pattern that&#8217;s limited to classes. You can write getters and setters with different types in object literals.<\/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\">makeThing<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #267F99;\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #0000ff;\">get<\/span> <span class=\"pl-en\">size<\/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 style=\"color: #0000ff;\">return<\/span> <span class=\"pl-s1\">size<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">,<\/span>\r\n        <span style=\"color: #0000ff;\">set<\/span> <span class=\"pl-en\">size<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n            <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">num<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #267F99;\">Number<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n            <span style=\"color: #148A14;\">\/\/ Don't allow NaN and stuff.<\/span>\r\n            <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-c1\">!<\/span><span style=\"color: #267F99;\">Number<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">isFinite<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">num<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n                <span class=\"pl-s1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">;<\/span>\r\n                <span style=\"color: #0000ff;\">return<\/span><span class=\"pl-kos\">;<\/span>\r\n            <span class=\"pl-kos\">}<\/span>\r\n\r\n            <span class=\"pl-s1\">size<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">num<\/span><span class=\"pl-kos\">;<\/span>\r\n        <span class=\"pl-kos\">}<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>In fact, we&#8217;ve added syntax to interfaces\/object types to support different reading\/writing types on properties.<\/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;\">\/\/ Now valid!<\/span>\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">Thing<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">get<\/span> <span class=\"pl-c1\">size<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #0000ff;\">number<\/span>\r\n    <span style=\"color: #0000ff;\">set<\/span> <span class=\"pl-c1\">size<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>One limitation of using different types for reading and writing properties is that the type for reading a property has to be assignable to the type that you&#8217;re writing. In other words, the getter type has to be assignable to the setter. This ensures some level of consistency, so that a property is always assignable to itself.<\/p>\n<p>For more information on this feature, take a look at <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42425\">the implementing pull request<\/a>.<\/p>\n<h2><code>override<\/code> and the <code>--noImplicitOverride<\/code> Flag<\/h2>\n<p>When extending classes in JavaScript, the language makes it super easy (pun intended) to override methods &#8211; but unfortunately, there are some mistakes that you can run into.<\/p>\n<p>One big one is missing renames. For example, take the following classes:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">SomeComponent<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-en\">show<\/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-en\">hide<\/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;\">class<\/span> <span style=\"color: #267F99;\">SpecializedComponent<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267F99;\">SomeComponent<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-en\">show<\/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-en\">hide<\/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><\/pre>\n<\/div>\n<p><code>SpecializedComponent<\/code> subclasses <code>SomeComponent<\/code>, and overrides the <code>show<\/code> and <code>hide<\/code> methods. What happens if someone decides to rip out <code>show<\/code> and <code>hide<\/code> and replace them with a single method?<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"> class SomeComponent {\r\n<span style=\"background-color: rgb(255, 238, 240);color: rgb(179, 29, 40);\">-    show() {<\/span>\r\n<span style=\"background-color: rgb(255, 238, 240);color: rgb(179, 29, 40);\">-        \/\/ ...<\/span>\r\n<span style=\"background-color: rgb(255, 238, 240);color: rgb(179, 29, 40);\">-    }<\/span>\r\n<span style=\"background-color: rgb(255, 238, 240);color: rgb(179, 29, 40);\">-    hide() {<\/span>\r\n<span style=\"background-color: rgb(255, 238, 240);color: rgb(179, 29, 40);\">-        \/\/ ...<\/span>\r\n<span style=\"background-color: rgb(255, 238, 240);color: rgb(179, 29, 40);\">-    }<\/span>\r\n<span style=\"background-color: rgb(240, 255, 244);color: rgb(34, 134, 58);\">+    setVisible(value: boolean) {<\/span>\r\n<span style=\"background-color: rgb(240, 255, 244);color: rgb(34, 134, 58);\">+        \/\/ ...<\/span>\r\n<span style=\"background-color: rgb(240, 255, 244);color: rgb(34, 134, 58);\">+    }<\/span>\r\n }\r\n class SpecializedComponent extends SomeComponent {\r\n     show() {\r\n         \/\/ ...\r\n     }\r\n     hide() {\r\n         \/\/ ...\r\n     }\r\n }<\/pre>\n<\/div>\n<p><em>Oh no!<\/em> Our <code>SpecializedComponent<\/code> didn&#8217;t get updated. Now it&#8217;s just adding these two useless <code>show<\/code> and <code>hide<\/code> methods that probably won&#8217;t get called.<\/p>\n<p>Part of the issue here is that a user can&#8217;t make it clear whether they meant to add a new method, or to override an existing one. That&#8217;s why TypeScript 4.3 adds the <code>override<\/code> keyword.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">SpecializedComponent<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267F99;\">SomeComponent<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-en\">override<\/span> <span class=\"pl-s1\">show<\/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-en\">override<\/span> <span class=\"pl-s1\">hide<\/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><\/pre>\n<\/div>\n<p>When a method is marked with <code>override<\/code>, TypeScript will always make sure that a method with the same name exists in a the base class.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">SomeComponent<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-en\">setVisible<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">value<\/span>: <span style=\"color: #0000ff;\">boolean<\/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;\">class<\/span> <span style=\"color: #267F99;\">SpecializedComponent<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267F99;\">SomeComponent<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-en\">override<\/span> <span class=\"pl-s1\">show<\/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! This method can't be marked with 'override' because it's not declared in 'SomeComponent'.<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>This is a big improvement, but it doesn&#8217;t help if you <em>forget<\/em> to write <code>override<\/code> on a method &#8211; and that&#8217;s a big mistake users can run into also.<\/p>\n<p>For example, you might accidentally &#8220;trample over&#8221; a method that exists in a base class without realizing 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;\">class<\/span> <span style=\"color: #267F99;\">Base<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-en\">someHelperMethod<\/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;\">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 style=\"color: #148A14;\">\/\/ Oops! We weren't trying to override here,<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ we just needed to write a local helper method.<\/span>\r\n    <span class=\"pl-en\">someHelperMethod<\/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><\/pre>\n<\/div>\n<p>That&#8217;s why TypeScript 4.3 <em>also<\/em> provides a new <code>--noImplicitOverride<\/code> flag. When this option is turned on, it becomes an error to override any method from a superclass unless you explicitly use an <code>override<\/code> keyword. In that last example, TypeScript would error under <code>--noImplicitOverride<\/code>, and give us a clue that we probably need to rename our method inside of <code>Derived<\/code>.<\/p>\n<p>We&#8217;d like to extend our thanks to our community for the implementation here. The work for these items was implemented in <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/39669\">a pull request<\/a> by <a href=\"https:\/\/github.com\/Kingwl\">Wenlu Wang<\/a>, though an earlier pull request implementing only the <code>override<\/code> keyword by <a href=\"https:\/\/github.com\/pcj\">Paul Cody Johnston<\/a> served as a basis for direction and discussion. We extend our gratitude for putting in the time for these features.<\/p>\n<h2>Template String Type Improvements<\/h2>\n<p>In recent versions, TypeScript introduced a new type construct: template string types. These are types that either construct new string-like types by concatenating&#8230;<\/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;\">Color<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"red\"<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #a31515;\">\"blue\"<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Quantity<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"one\"<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #a31515;\">\"two\"<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-en\">type<\/span> <span style=\"color: #267F99;\">SeussFish<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span><span style=\"color: #267F99;\">Quantity<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #267F99;\">Color<\/span><span class=\"pl-kos\">}<\/span><\/span> fish`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148A14;\">\/\/ same as<\/span>\r\n<span style=\"color: #148A14;\">\/\/   type SeussFish = \"one fish\" | \"two fish\"<\/span>\r\n<span style=\"color: #148A14;\">\/\/                  | \"red fish\" | \"blue fish\";<\/span><\/pre>\n<\/div>\n<p>&#8230;or match patterns of other string-like 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 class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s1<\/span>: <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s2<\/span>: <span style=\"color: #a31515;\">`1-2-3`<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Works!<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s2<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>The first change we made is just in when TypeScript will infer a template string type. When a template string is <em>contextually typed<\/em> by a string-literal-like type (i.e. when TypeScript sees we&#8217;re passing a template string to something that takes a literal type) it will try to give that expression a template type.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-s1\">bar<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">s<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>string<span class=\"pl-kos\">}<\/span><\/span>`<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Previously an error, now works!<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>s<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>This also kicks in when inferring types, and the type parameter <code>extends string<\/code><\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-s1\">f<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">string<\/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 style=\"color: #267F99;\">T<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Previously: string<\/span>\r\n<span style=\"color: #148A14;\">\/\/ Now       : `hello-${string}`<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x2<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">f<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">`hello <span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>s<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>The second major change here is that TypeScript can now better-relate, and <em>infer between<\/em>, different template string types.<\/p>\n<p>To see this, take the following example 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-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s1<\/span>: <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s2<\/span>: <span style=\"color: #a31515;\">`1-2-3`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s3<\/span>: <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-2-3`<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s2<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s3<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>When checking against a string literal type like on <code>s2<\/code>, TypeScript could match against the string contents and figure out that <code>s2<\/code> was compatible with <code>s1<\/code> in the first assignment; however, as soon as it saw another template string, it just gave up. As a result, assignments like <code>s3<\/code> to <code>s1<\/code> just didn&#8217;t work.<\/p>\n<p>TypeScript now actually does the work to prove whether or not each part of a template string can successfully match. You can now mix and match template strings with different substitutions and TypeScript will do a good job to figure out whether they&#8217;re really compatible.<\/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\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s1<\/span>: <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s2<\/span>: <span style=\"color: #a31515;\">`1-2-3`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s3<\/span>: <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-2-3`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s4<\/span>: <span style=\"color: #a31515;\">`1-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-3`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s5<\/span>: <span style=\"color: #a31515;\">`1-2-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-en\">declare<\/span> <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">s6<\/span>: <span style=\"color: #a31515;\">`<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>-2-<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>number<span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Now *all of these* work!<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s2<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s3<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s4<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s5<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-s1\">s1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">s6<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>In doing this work, we were also sure to add better inference capabilities. You can see an example of these in action:<\/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\">foo<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">V<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">arg<\/span>: `<span class=\"pl-c1\">*<\/span>${<span style=\"color: #267F99;\">V<\/span><span class=\"pl-kos\">}<\/span><span class=\"pl-c1\">*<\/span>`<span class=\"pl-kos\">)<\/span>: <span style=\"color: #267F99;\">V<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">test<\/span><span class=\"pl-c1\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">s<\/span>: <span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">n<\/span>: <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">b<\/span>: <span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">t<\/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-s1\">x1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">\"*hello*\"<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>            <span style=\"color: #148A14;\">\/\/ \"hello\"<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x2<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">\"**hello**\"<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>          <span style=\"color: #148A14;\">\/\/ \"*hello*\"<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x3<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">`*<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>s<span class=\"pl-kos\">}<\/span><\/span>*`<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>    <span style=\"color: #148A14;\">\/\/ string<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x4<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">`*<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>n<span class=\"pl-kos\">}<\/span><\/span>*`<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>    <span style=\"color: #148A14;\">\/\/ `${number}`<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x5<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">`*<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>b<span class=\"pl-kos\">}<\/span><\/span>*`<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>    <span style=\"color: #148A14;\">\/\/ \"true\" | \"false\"<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x6<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">`*<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>t<span class=\"pl-kos\">}<\/span><\/span>*`<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>    <span style=\"color: #148A14;\">\/\/ `${T}`<\/span>\r\n    <span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x7<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span style=\"color: #a31515;\">`**<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span>s<span class=\"pl-kos\">}<\/span><\/span>**`<\/span> <span style=\"color: #0000ff;\">as<\/span> <span class=\"pl-smi\">const<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>  <span style=\"color: #148A14;\">\/\/ `*${string}*`<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>For more information, see <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/43376\">the original pull request on leveraging contextual types<\/a>, along with <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/43361\">the pull request that improved inference and checking between template types<\/a>.<\/p>\n<h2>ECMAScript <code>#private<\/code> Class Elements<\/h2>\n<p>TypeScript 4.3 expands which elements in a class can be given <code>#private<\/code> <code>#names<\/code> to make them truly private at run-time. In addition to properties, methods and accessors can also be given private names.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Foo<\/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: #148A14;\">\/\/...<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">get<\/span> #<span class=\"pl-en\">someValue<\/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: #09885A;\">100<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n\r\n    <span class=\"pl-en\">publicMethod<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ These work.<\/span>\r\n        <span style=\"color: #148A14;\">\/\/ We can access private-named members inside this class.<\/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><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\">someValue<\/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: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/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 style=\"color: #148A14;\">\/\/        ~~~~~~~~~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n<span style=\"color: #148A14;\">\/\/ Property '#someMethod' is not accessible<\/span>\r\n<span style=\"color: #148A14;\">\/\/ outside class 'Foo' because it has a private identifier.<\/span>\r\n\r\n<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">.<\/span>#<span class=\"pl-c1\">someValue<\/span><span class=\"pl-kos\">;<\/span>\r\n<span style=\"color: #148A14;\">\/\/        ~~~~~~~~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n<span style=\"color: #148A14;\">\/\/ Property '#someValue' is not accessible<\/span>\r\n<span style=\"color: #148A14;\">\/\/ outside class 'Foo' because it has a private identifier.<\/span><\/pre>\n<\/div>\n<p>Even more broadly, static members can now also have private names.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Foo<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">static<\/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 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: #267F99;\">Foo<\/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 style=\"color: #148A14;\">\/\/  ~~~~~~~~~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error!<\/span>\r\n<span style=\"color: #148A14;\">\/\/ Property '#someMethod' is not accessible<\/span>\r\n<span style=\"color: #148A14;\">\/\/ outside class 'Foo' because it has a private identifier.<\/span><\/pre>\n<\/div>\n<p>This feature was authored <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42458\">in a pull request<\/a> from our friends at Bloomberg &#8211; written by <a href=\"https:\/\/github.com\/dragomirtitian\">Titian Cernicova-Dragomir<\/a>and <a href=\"https:\/\/github.com\/mkubilayk\">Kubilay Kahveci<\/a>, with support and expertise from <a href=\"https:\/\/github.com\/joeywatts\">Joey Watts<\/a>, <a href=\"https:\/\/github.com\/robpalme\">Rob Palmer<\/a>, and <a href=\"https:\/\/github.com\/tim-mc\">Tim McClure<\/a>. We&#8217;d like to extend our thanks to all of them!<\/p>\n<h2>Always-Truthy Promise Checks<\/h2>\n<p>Under <code>strictNullChecks<\/code>, checking whether a <code>Promise<\/code> is &#8220;truthy&#8221; in a conditional will trigger an 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;\">async<\/span> <span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">foo<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #267F99;\">Promise<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #0000ff;\">boolean<\/span><span class=\"pl-kos\">&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">false<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">async<\/span> <span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">bar<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span>: <span style=\"color: #267F99;\">Promise<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #0000ff;\">string<\/span><span class=\"pl-kos\">&gt;<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-en\">foo<\/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;\">\/\/  ~~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Error!<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ This condition will always return true since<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ this 'Promise&lt;boolean&gt;' appears to always be defined.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Did you forget to use 'await'?<\/span>\r\n        <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">\"true\"<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-kos\">}<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #a31515;\">\"false\"<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p><a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/39175\">This change<\/a> was contributed by <a href=\"https:\/\/github.com\/Jack-Works\">Jack Works<\/a>, and we extend our thanks to them!<\/p>\n<h2><code>static<\/code> Index Signatures<\/h2>\n<p>Index signatures allow us set more properties on a value than a type explicitly declares.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Foo<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-c1\">hello<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-c1\">world<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">1234<\/span><span class=\"pl-kos\">;<\/span>\r\n\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;\">string<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">|<\/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;\">let<\/span> <span class=\"pl-s1\">instance<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Valid assigment<\/span>\r\n<span class=\"pl-s1\">instance<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"whatever\"<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">42<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Has type 'string | number | undefined'.<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">instance<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"something\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>Up until now, an index signature could only be declared on the instance side of a class. Thanks to <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/37797\">a pull request<\/a> from <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/37797\">Wenlu Wang<\/a>, index signatures can now be declared as <code>static<\/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;\">class<\/span> <span style=\"color: #267F99;\">Foo<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">static<\/span> <span class=\"pl-c1\">hello<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #a31515;\">\"hello\"<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #0000ff;\">static<\/span> <span class=\"pl-c1\">world<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">1234<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">static<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">propName<\/span>: <span class=\"pl-s1\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">|<\/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: #148A14;\">\/\/ Valid.<\/span>\r\n<span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"whatever\"<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">42<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Has type 'string | number | undefined'<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> <span class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #267F99;\">Foo<\/span><span class=\"pl-kos\">[<\/span><span style=\"color: #a31515;\">\"something\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>The same sorts of rules apply for index signatures on the static side of a class as they do for the instance side &#8211; namely, that every other static property has to be compatible with the index 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;\">class<\/span> <span style=\"color: #267F99;\">Foo<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span style=\"color: #0000ff;\">static<\/span> <span class=\"pl-c1\">prop<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #0000ff;\">true<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span style=\"color: #148A14;\">\/\/     ~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Error! Property 'prop' of type 'boolean'<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ is not assignable to string index type<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ 'string | number | undefined'.<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">static<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-s1\">propName<\/span>: <span class=\"pl-s1\">string<\/span><span class=\"pl-kos\">]<\/span>: <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-c1\">|<\/span> <span style=\"color: #0000ff;\">undefined<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<h2>Import Statement Completions<\/h2>\n<p>One of the biggest pain-points users run into with import and export statements in JavaScript is the order &#8211; specifically that imports are written as<\/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 class=\"pl-s1\">func<\/span> <span class=\"pl-kos\">}<\/span> <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\">\".\/module.js\"<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>instead of<\/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\">from<\/span> <span style=\"color: #a31515;\">\".\/module.js\"<\/span> <span style=\"color: #0000ff;\">import<\/span> <span class=\"pl-kos\">{<\/span> <span class=\"pl-s1\">func<\/span> <span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">;<\/span><\/pre>\n<\/div>\n<p>This causes some pain when writing out a full import statement from scratch because auto-complete wasn&#8217;t able to work correctly. For example, if you start writing something like <code>import {<\/code>, TypeScript has no idea what module you&#8217;re planning on importing from, so it couldn&#8217;t provide any scoped-down completions.<\/p>\n<p>To alleviate this, we&#8217;ve leveraged the power of auto-imports! Auto-imports already deal with the issue of not being able to narrow down completions from a specific module &#8211; their whole point is to provide every possible export and automatically insert an import statement at the top of your file.<\/p>\n<p>So when you now start writing an <code>import<\/code> statement that doesn&#8217;t have a path, we&#8217;ll provide you with a list of possible imports. When you commit a completion, we&#8217;ll complete the full import statement, including the path that you were going to write.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2021\/03\/111011663-f53c7580-834e-11eb-9a2a-3dc3ea24d0791.gif\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" alt=\"Import statement completions\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2021\/03\/111011663-f53c7580-834e-11eb-9a2a-3dc3ea24d0791.gif\" \/><\/a><\/p>\n<p>This work requires editors that specifically support the feature. You&#8217;ll be able to try this out by using the latest <a href=\"https:\/\/code.visualstudio.com\/insiders\/\" rel=\"nofollow\">Insiders versions of Visual Studio Code<\/a>.<\/p>\n<p>For more information, take a look at <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/43149\">the implementing pull request<\/a>!<\/p>\n<h2>Editor Support for <code>@link<\/code> Tags<\/h2>\n<p>TypeScript can now understand <code>@link<\/code> tags, and will try to resolve declarations that they link to. What this means is that you&#8217;ll be able to hover over names within <code>@link<\/code> tags and get quick information, or use commands like go-to-definition or find-all-references.<\/p>\n<p>For example, you&#8217;ll be able to go-to-definition on <code>bar<\/code> in <code>@link bar<\/code> in the example below and a TypeScript-supported editor will jump to <code>bar<\/code>&#8216;s function declaration.<\/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;\">\/**<\/span>\r\n<span style=\"color: #148A14;\"> * This function depends on {<span class=\"pl-k\">@link<\/span> bar}<\/span>\r\n<span style=\"color: #148A14;\"> *\/<\/span>\r\n<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\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">bar<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>For more information, see <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/41877\">the pull request on GitHub<\/a>!<\/p>\n<h2>Breaking Changes<\/h2>\n<h3><code>lib.d.ts<\/code> Changes<\/h3>\n<p>As with every TypeScript version, declarations for <code>lib.d.ts<\/code> (especially the declarations generated for web contexts), have changed.\nIn this release, we leveraged <a href=\"https:\/\/github.com\/mdn\/browser-compat-data\">Mozilla&#8217;s browser-compat-data<\/a> to remove APIs that no browser implements.\nWhile it is unlike that you are using them, APIs such as <code>Account<\/code>, <code>AssertionOptions<\/code>, <code>RTCStatsEventInit<\/code>, <code>MSGestureEvent<\/code>, <code>DeviceLightEvent<\/code>, <code>MSPointerEvent<\/code>, <code>ServiceWorkerMessageEvent<\/code>, and <code>WebAuthentication<\/code> have all been removed from <code>lib.d.ts<\/code>.\nThis is discussed <a href=\"https:\/\/github.com\/microsoft\/TypeScript-DOM-lib-generator\/issues\/991\">in some detail here<\/a>.<\/p>\n<h3>Errors on Always-Truthy Promise Checks<\/h3>\n<p>Under <code>strictNullChecks<\/code>, using a <code>Promise<\/code> that always appears to be defined within a condition check is now considered an 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;\">declare<\/span> <span style=\"color: #0000ff;\">var<\/span> <span class=\"pl-s1\">p<\/span>: <span style=\"color: #267F99;\">Promise<\/span><span class=\"pl-kos\">&lt;<\/span><span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">p<\/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!<\/span>\r\n<span style=\"color: #148A14;\">\/\/ This condition will always return true since<\/span>\r\n<span style=\"color: #148A14;\">\/\/ this 'Promise&lt;number&gt;' appears to always be defined.<\/span>\r\n<span style=\"color: #148A14;\">\/\/<\/span>\r\n<span style=\"color: #148A14;\">\/\/ Did you forget to use 'await'?<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/39175\">see the original change<\/a>.<\/p>\n<h3>Union Enums Cannot Be Compared to Arbitrary Numbers<\/h3>\n<p>Certain <code>enum<\/code>s are considered <em>union <code>enum<\/code>s<\/em> when their members are either automatically filled in, or trivially written. In those cases, an enum can recall each value that it potentially represents.<\/p>\n<p>In TypeScript 4.3, if a value with a union <code>enum<\/code> type is compared with a numeric literal that it could never be equal to, then the type-checker will issue an 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;\">enum<\/span> <span style=\"color: #267F99;\">E<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span class=\"pl-c1\">A<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">,<\/span>\r\n  <span class=\"pl-c1\">B<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">1<\/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\">doSomething<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">x<\/span>: <span style=\"color: #267F99;\">E<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #148A14;\">\/\/ Error! This condition will always return 'false' since the types 'E' and '-1' have no overlap.<\/span>\r\n  <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">===<\/span> <span class=\"pl-c1\">-<\/span><span style=\"color: #09885A;\">1<\/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>As a workaround, you can re-write an annotation to include the appropriate literal type.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><span style=\"color: #0000ff;\">enum<\/span> <span style=\"color: #267F99;\">E<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span class=\"pl-c1\">A<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">,<\/span>\r\n  <span class=\"pl-c1\">B<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">1<\/span><span class=\"pl-kos\">,<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Include -1 in the type, if we're really certain that -1 can come through.<\/span>\r\n<span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">doSomething<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">x<\/span>: <span style=\"color: #267F99;\">E<\/span> <span class=\"pl-c1\">|<\/span> <span class=\"pl-c1\">-<\/span><span style=\"color: #09885A;\">1<\/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 class=\"pl-s1\">x<\/span> <span class=\"pl-c1\">===<\/span> <span class=\"pl-c1\">-<\/span><span style=\"color: #09885A;\">1<\/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>You can also use a type-assertion on the value.<\/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;\">enum<\/span> <span style=\"color: #267F99;\">E<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span class=\"pl-c1\">A<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">,<\/span>\r\n  <span class=\"pl-c1\">B<\/span> <span class=\"pl-c1\">=<\/span> <span style=\"color: #09885A;\">1<\/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\">doSomething<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">x<\/span>: <span style=\"color: #267F99;\">E<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #148A14;\">\/\/ Use a type asertion on 'x' because we know we're not actually just dealing with values from 'E'.<\/span>\r\n  <span style=\"color: #0000ff;\">if<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">x<\/span> <span style=\"color: #0000ff;\">as<\/span> <span style=\"color: #0000ff;\">number<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">===<\/span> <span class=\"pl-c1\">-<\/span><span style=\"color: #09885A;\">1<\/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>Alternatively, you can re-declare your enum to have a non-trivial initializer so that any number is both assignable and comparable to that enum. This may be useful if the intent is for the enum to specify a few well-known values.<\/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;\">enum<\/span> <span style=\"color: #267F99;\">E<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span style=\"color: #148A14;\">\/\/ the leading + on 0 opts TypeScript out of inferring a union enum.<\/span>\r\n  <span class=\"pl-c1\">A<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-c1\">+<\/span><span style=\"color: #09885A;\">0<\/span><span class=\"pl-kos\">,<\/span>\r\n  <span class=\"pl-c1\">B<\/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>For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/42472\">see the original change<\/a><\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>You can keep track of the upcoming release candidate and stable releases by checking up on the <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/42762\">TypeScript 4.3 Iteration Plan<\/a>. We&#8217;re looking to get feedback on this beta (or better yet, <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/nightly-builds.html\" rel=\"nofollow\">our nightly releases<\/a>), so give it a shot today!<\/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 Beta of TypeScript 4.3! To get started using the beta, you can get it through 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 Visual Studio Code and Sublime Text. Let&#8217;s dive [&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-2934","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 Beta of TypeScript 4.3! To get started using the beta, you can get it through 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 Visual Studio Code and Sublime Text. Let&#8217;s dive [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2934","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=2934"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2934\/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=2934"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=2934"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=2934"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}