{"id":2343,"date":"2019-10-24T10:42:16","date_gmt":"2019-10-24T18:42:16","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=2343"},"modified":"2019-10-24T10:42:16","modified_gmt":"2019-10-24T18:42:16","slug":"announcing-typescript-3-7-rc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-3-7-rc\/","title":{"rendered":"Announcing TypeScript 3.7 RC"},"content":{"rendered":"<p>We&#8217;re pleased to announce TypeScript 3.7 RC, the release candidate of TypeScript 3.7. Between now and the final release, we expect no further changes except for 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;\"><code>npm install typescript@rc<\/code><\/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-37rc\" 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>TypeScript 3.7 RC includes some of our most highly-requested features!<\/p>\n<ul>\n<li><a href=\"#optional-chaining\">Optional Chaining<\/a><\/li>\n<li><a href=\"#nullish-coalescing\">Nullish Coalescing<\/a><\/li>\n<li><a href=\"#assertion-functions\">Assertion Functions<\/a><\/li>\n<li><a href=\"#better-support-for-never-returning-functions\">Better Support for <code>never<\/code>-Returning Functions<\/a><\/li>\n<li><a href=\"#more-recursive-type-aliases\">(More) Recursive Type Aliases<\/a><\/li>\n<li><a href=\"#--declaration-and--allowjs\"><code>--declaration<\/code> and <code>--allowJs<\/code><\/a><\/li>\n<li><a href=\"#build-free-editing-with-project-references\">Build-Free Editing with Project References<\/a><\/li>\n<li><a href=\"#uncalled-function-checks\">Uncalled Function Checks<\/a><\/li>\n<li><a href=\"#ts-nocheck-in-typescript-files\"><code>\/\/ @ts-nocheck<\/code> in TypeScript Files<\/a><\/li>\n<li><a href=\"#semicolon-formatter-option\">Semicolon Formatter Option<\/a><\/li>\n<li><a href=\"#breaking-Changes\">Breaking Changes<\/a>\n<ul>\n<li><a href=\"#dom-changes\">DOM Changes<\/a><\/li>\n<li><a href=\"#function-truthy-checks\">Function Truthy Checks<\/a><\/li>\n<li><a href=\"#local-and-imported-type-declarations-now-conflict\">Local and Imported Type Declarations Now Conflict<\/a><\/li>\n<li><a href=\"#api-changes\">API Changes<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Let&#8217;s dive in and see what&#8217;s new, starting with the highlight feature of 3.7: Optional Chaining.<\/p>\n<h2 id=\"optional-chaining\">Optional Chaining<\/h2>\n<p>TypeScript 3.7 implements one of the most highly-demanded ECMAScript features yet: optional chaining! Our team has been heavily involved in TC39 to champion the feature to Stage 3 so that we can bring it to all TypeScript users.<\/p>\n<p>So what is optional chaining? Well at its core, optional chaining lets us write code where we can immediately stop running some expressions if we run into a <code>null<\/code> or <code>undefined<\/code>. The star of the show in optional chaining is the new <code>?.<\/code> operator for <em>optional property accesses<\/em>. When we write code like<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">foo<\/span>?.<span class=\"pl-smi\">bar<\/span>.<span class=\"pl-en\">baz<\/span>();<\/code><\/pre>\n<\/div>\n<p>this is a way of saying that when <code>foo<\/code> is defined, <code>foo.bar.baz()<\/code> will be computed; but when <code>foo<\/code> is <code>null<\/code> or <code>undefined<\/code>, stop what we&#8217;re doing and just return <code>undefined<\/code>.&#8221;<\/p>\n<p>More plainly, that code snippet is the same as writing the following.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> (<span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #0000ff;\">null<\/span> <span class=\"pl-k\">||<\/span> <span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #0000ff;\">undefined<\/span>) <span class=\"pl-k\">?<\/span>\r\n    <span style=\"color: #0000ff;\">undefined<\/span> <span class=\"pl-k\">:<\/span>\r\n    <span class=\"pl-smi\">foo<\/span>.<span class=\"pl-smi\">bar<\/span>.<span class=\"pl-en\">baz<\/span>();<\/code><\/pre>\n<\/div>\n<p>Note that if <code>bar<\/code> is <code>null<\/code> or <code>undefined<\/code>, our code will still hit an error accessing <code>baz<\/code>. Likewise, if <code>baz<\/code> is <code>null<\/code> or <code>undefined<\/code>, we&#8217;ll hit an error at the call site. <code>?.<\/code> only checks for whether the value on the left of it is <code>null<\/code> or <code>undefined<\/code> &#8211; not any of the subsequent properties.<\/p>\n<p>You might find yourself using <code>?.<\/code> to replace a lot of code that performs intermediate property checks using the <code>&amp;&amp;<\/code> operator.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #148A14;\">\/\/ Before<\/span>\r\n<span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">&amp;&amp;<\/span> <span class=\"pl-smi\">foo<\/span>.<span class=\"pl-smi\">bar<\/span> <span class=\"pl-k\">&amp;&amp;<\/span> <span class=\"pl-smi\">foo<\/span>.<span class=\"pl-smi\">bar<\/span>.<span class=\"pl-smi\">baz<\/span>) {\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ After-ish<\/span>\r\n<span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">foo<\/span>?.<span class=\"pl-smi\">bar<\/span>?.<span class=\"pl-smi\">baz<\/span>) {\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>Keep in mind that <code>?.<\/code> acts differently than those <code>&amp;&amp;<\/code> operations since <code>&amp;&amp;<\/code> will act specially on &#8220;falsy&#8221; values (e.g. the empty string, <code>0<\/code>, <code>NaN<\/code>, and, well, <code>false<\/code>).<\/p>\n<p>Optional chaining also includes two other operations. First there&#8217;s <em>optional element access<\/em> which acts similarly to optional property accesses, but allows us to access non-identifier properties (e.g. arbitrary strings, numbers, and symbols):<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\"> * Get the first element of the array if we have an array.<\/span>\r\n<span style=\"color: #148A14;\"> * Otherwise return undefined.<\/span>\r\n<span style=\"color: #148A14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">function<\/span> tryGetFirstElement&lt;<span style=\"color: #267F99;\">T<\/span>&gt;(<span class=\"pl-v\">arr<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>[]) {\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">arr<\/span>?.[<span style=\"color: #09885A;\">0<\/span>];\r\n    <span style=\"color: #148A14;\">\/\/ equivalent to<\/span>\r\n    <span style=\"color: #148A14;\">\/\/   return (arr === null || arr === undefined) ?<\/span>\r\n    <span style=\"color: #148A14;\">\/\/       undefined :<\/span>\r\n    <span style=\"color: #148A14;\">\/\/       arr[0];<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>There&#8217;s also <em>optional call<\/em>, which allows us to conditionally call expressions if they&#8217;re not <code>null<\/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;\"><code><span style=\"color: #0000ff;\">async<\/span> <span style=\"color: #0000ff;\">function<\/span> makeRequest(<span class=\"pl-v\">url<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>, <span class=\"pl-en\">log<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> (<span class=\"pl-v\">msg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>) <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #0000ff;\">void<\/span>) {\r\n    <span class=\"pl-en\">log<\/span>?.(<span style=\"color: #a31515;\"><span class=\"pl-pds\">`<\/span>Request started at ${<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Date<\/span>().<span class=\"pl-en\">toISOString<\/span>()}<span class=\"pl-pds\">`<\/span><\/span>);\r\n    <span style=\"color: #148A14;\">\/\/ equivalent to<\/span>\r\n    <span style=\"color: #148A14;\">\/\/   if (log !== null &amp;&amp; log !== undefined) {<\/span>\r\n    <span style=\"color: #148A14;\">\/\/       log(`Request started at ${new Date().toISOString()}`);<\/span>\r\n    <span style=\"color: #148A14;\">\/\/   }<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">const<\/span> result <span class=\"pl-k\">=<\/span> (<span style=\"color: #0000ff;\">await<\/span> <span class=\"pl-en\">fetch<\/span>(<span class=\"pl-smi\">url<\/span>)).<span class=\"pl-en\">json<\/span>();\r\n\r\n    <span class=\"pl-en\">log<\/span>?.(<span style=\"color: #a31515;\"><span class=\"pl-pds\">`<\/span>Request finished at at ${<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Date<\/span>().<span class=\"pl-en\">toISOString<\/span>()}<span class=\"pl-pds\">`<\/span><\/span>);\r\n\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">result<\/span>;\r\n}<\/code><\/pre>\n<\/div>\n<p>The &#8220;short-circuiting&#8221; behavior that optional chains have is limited to both &#8220;ordinary&#8221; and optional property accesses, calls, element accesses &#8211; it doesn&#8217;t expand any further out from these expressions. In other words,<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">let<\/span> result <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">foo<\/span>?.<span class=\"pl-smi\">bar<\/span> <span class=\"pl-k\">\/<\/span> <span class=\"pl-en\">someComputation<\/span>()<\/code><\/pre>\n<\/div>\n<p>doesn&#8217;t stop the division or <code>someComputation()<\/code> call from occurring. It&#8217;s equivalent to<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">let<\/span> temp <span class=\"pl-k\">=<\/span> (<span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #0000ff;\">null<\/span> <span class=\"pl-k\">||<\/span> <span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #0000ff;\">undefined<\/span>) <span class=\"pl-k\">?<\/span>\r\n    <span style=\"color: #0000ff;\">undefined<\/span> <span class=\"pl-k\">:<\/span>\r\n    <span class=\"pl-smi\">foo<\/span>.<span class=\"pl-smi\">bar<\/span>;\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> result <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">temp<\/span> <span class=\"pl-k\">\/<\/span> <span class=\"pl-en\">someComputation<\/span>();<\/code><\/pre>\n<\/div>\n<p>That might result in dividing <code>undefined<\/code>, which is why in <code>strictNullChecks<\/code>, the following is 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;\"><code><span style=\"color: #0000ff;\">function<\/span> barPercentage(<span class=\"pl-v\">foo<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> { bar<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span> }) {\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">foo<\/span>?.<span class=\"pl-smi\">bar<\/span> <span class=\"pl-k\">\/<\/span> <span style=\"color: #09885A;\">100<\/span>;\r\n    <span style=\"color: #148A14;\">\/\/     ~~~~~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Error: Object is possibly undefined.<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>More more details, you can <a href=\"https:\/\/github.com\/tc39\/proposal-optional-chaining\/\">read up on the proposal<\/a> and <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/33294\">view the original pull request<\/a>.<\/p>\n<h2 id=\"nullish-coalescing\">Nullish Coalescing<\/h2>\n<p>The <em>nullish coalescing operator<\/em> is another upcoming ECMAScript feature that goes hand-in-hand with optional chaining, and which our team has been deeply involved in championing.<\/p>\n<p>You can think of this feature &#8211; the <code>??<\/code> operator &#8211; as a way to &#8220;fall back&#8221; to a default value when dealing with <code>null<\/code> or <code>undefined<\/code>. When we write code like<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">??<\/span> <span class=\"pl-en\">bar<\/span>();<\/code><\/pre>\n<\/div>\n<p>this is a new way to say that the value <code>foo<\/code> will be used when it&#8217;s &#8220;present&#8221;; but when it&#8217;s <code>null<\/code> or <code>undefined<\/code>, calculate <code>bar()<\/code> in its place.<\/p>\n<p>Again, the above code is equivalent to the following.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">let<\/span> x <span class=\"pl-k\">=<\/span> (<span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">!==<\/span> <span style=\"color: #0000ff;\">null<\/span> <span class=\"pl-k\">&amp;&amp;<\/span> <span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">!==<\/span> <span style=\"color: #0000ff;\">undefined<\/span>) <span class=\"pl-k\">?<\/span>\r\n    <span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">:<\/span>\r\n    <span class=\"pl-en\">bar<\/span>();<\/code><\/pre>\n<\/div>\n<p>The <code>??<\/code> operator can replace uses of <code>||<\/code> when trying to use a default value. For example, the following code snippet tries to fetch the volume that was last saved in <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/localStorage\" rel=\"nofollow\"><code>localStorage<\/code><\/a> (if it ever was); however, it has a bug because it uses <code>||<\/code>.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> initializeAudio() {\r\n    <span style=\"color: #0000ff;\">let<\/span> volume <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">localStorage<\/span>.<span class=\"pl-smi\">volume<\/span> <span class=\"pl-k\">||<\/span> <span style=\"color: #09885A;\">0.5<\/span>\r\n\r\n    <span style=\"color: #148A14;\">\/\/ ...<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>When <code>localStorage.volume<\/code> is set to <code>0<\/code>, the page will set the volume to <code>0.5<\/code> which is unintended. <code>??<\/code> avoids some unintended behavior from <code>0<\/code>, <code>NaN<\/code> and <code>\"\"<\/code> being treated as falsy values.<\/p>\n<p>We owe a large thanks to community members <a href=\"https:\/\/github.com\/Kingwl\">Wenlu Wang<\/a> and <a href=\"https:\/\/github.com\/dragomirtitian\">Titian Cernicova Dragomir<\/a> for implementing this feature! For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/32883\">check out their pull request<\/a> and <a href=\"https:\/\/github.com\/tc39\/proposal-nullish-coalescing\/\">the nullish coalescing proposal repository<\/a>.<\/p>\n<h2 id=\"assertion-functions\">Assertion Functions<\/h2>\n<p>There&#8217;s a specific set of functions that <code>throw<\/code> an error if something unexpected happened. They&#8217;re called &#8220;assertion&#8221; functions. As an example, Node.js has a dedicated function for this called <code>assert<\/code>.<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span class=\"pl-en\">assert<\/span>(someValue <span class=\"pl-k\">===<\/span> <span style=\"color: #09885A;\">42<\/span>);<\/code><\/pre>\n<\/div>\n<p>In this example if <code>someValue<\/code> isn&#8217;t equal to <code>42<\/code>, then <code>assert<\/code> will throw an <code>AssertionError<\/code>.<\/p>\n<p>Assertions in JavaScript are often used to guard against improper types being passed in. For example,<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> <span class=\"pl-en\">multiply<\/span>(<span class=\"pl-smi\">x<\/span>, <span class=\"pl-smi\">y<\/span>) {\r\n    <span class=\"pl-en\">assert<\/span>(<span style=\"color: #0000ff;\">typeof<\/span> x <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>number<span class=\"pl-pds\">\"<\/span><\/span>);\r\n    <span class=\"pl-en\">assert<\/span>(<span style=\"color: #0000ff;\">typeof<\/span> y <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>number<span class=\"pl-pds\">\"<\/span><\/span>);\r\n\r\n    <span style=\"color: #0000ff;\">return<\/span> x <span class=\"pl-k\">*<\/span> y;\r\n}<\/code><\/pre>\n<\/div>\n<p>Unfortunately in TypeScript these checks could never be properly encoded. For loosely-typed code this meant TypeScript was checking less, and for slightly conservative code it often forced users to use type assertions..<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> yell(<span class=\"pl-v\">str<\/span>) {\r\n    <span class=\"pl-en\">assert<\/span>(<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">str<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>);\r\n\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">str<\/span>.<span class=\"pl-en\">toUppercase<\/span>();\r\n    <span style=\"color: #148A14;\">\/\/ Oops! We misspelled 'toUpperCase'.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ Would be great if TypeScript still caught this!<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>The alternative was to instead rewrite the code so that the language could analyze it, but this isn&#8217;t convenient.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> yell(<span class=\"pl-v\">str<\/span>) {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">str<\/span> <span class=\"pl-k\">!==<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">TypeError<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>str should have been a string.<span class=\"pl-pds\">\"<\/span><\/span>)\r\n    }\r\n    <span style=\"color: #148A14;\">\/\/ Error caught!<\/span>\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">str<\/span>.<span class=\"pl-en\">toUppercase<\/span>();\r\n}<\/code><\/pre>\n<\/div>\n<p>Ultimately the goal of TypeScript is to type existing JavaScript constructs in the least disruptive way. For that reason, TypeScript 3.7 introduces a new concept called &#8220;assertion signatures&#8221; which model these assertion functions.<\/p>\n<p>The first type of assertion signature models the way that Node&#8217;s <code>assert<\/code> function works. It ensures that whatever condition is being checked must be true for the remainder of the containing scope.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> assert(<span class=\"pl-v\">condition<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span>, <span class=\"pl-v\">msg<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>)<span class=\"pl-k\">:<\/span> <span class=\"pl-en\">asserts<\/span> <span class=\"pl-en\">condition<\/span> {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-k\">!<\/span><span class=\"pl-smi\">condition<\/span>) {\r\n        <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">AssertionError<\/span>(<span class=\"pl-smi\">msg<\/span>)\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p><code>asserts condition<\/code> says that whatever gets passed into the <code>condition<\/code> parameter must be true if the <code>assert<\/code> returns (because otherwise it would throw an error). That means that for the rest of the scope, that condition must be truthy. As an example, using this assertion function means we <em>do<\/em> catch our original <code>yell<\/code> example.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> yell(<span class=\"pl-v\">str<\/span>) {\r\n    <span class=\"pl-en\">assert<\/span>(<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">str<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>);\r\n\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">str<\/span>.<span class=\"pl-en\">toUppercase<\/span>();\r\n    <span style=\"color: #148A14;\">\/\/         ~~~~~~~~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ error: Property 'toUppercase' does not exist on type 'string'.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/        Did you mean 'toUpperCase'?<\/span>\r\n}\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> assert(<span class=\"pl-v\">condition<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span>, <span class=\"pl-v\">msg<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>)<span class=\"pl-k\">:<\/span> <span class=\"pl-en\">asserts<\/span> <span class=\"pl-en\">condition<\/span> {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-k\">!<\/span><span class=\"pl-smi\">condition<\/span>) {\r\n        <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">AssertionError<\/span>(<span class=\"pl-smi\">msg<\/span>)\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>The other type of assertion signature doesn&#8217;t check for a condition, but instead tells TypeScript that a specific variable or property has a different 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;\"><code><span style=\"color: #0000ff;\">function<\/span> assertIsString(<span class=\"pl-v\">val<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span>)<span class=\"pl-k\">:<\/span> <span class=\"pl-en\">asserts<\/span> <span class=\"pl-en\">val<\/span> <span style=\"color: #0000ff;\">is<\/span> <span style=\"color: #0000ff;\">string<\/span> {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">val<\/span> <span class=\"pl-k\">!==<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">AssertionError<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>Not a string!<span class=\"pl-pds\">\"<\/span><\/span>);\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>Here <code>asserts val is string<\/code> ensures that after any call to <code>assertIsString<\/code>, any variable passed in will be known to be a <code>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;\"><code><span style=\"color: #0000ff;\">function<\/span> yell(<span class=\"pl-v\">str<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span>) {\r\n    <span class=\"pl-en\">assertIsString<\/span>(<span class=\"pl-smi\">str<\/span>);\r\n\r\n    <span style=\"color: #148A14;\">\/\/ Now TypeScript knows that 'str' is a 'string'.<\/span>\r\n\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">str<\/span>.<span class=\"pl-en\">toUppercase<\/span>();\r\n    <span style=\"color: #148A14;\">\/\/         ~~~~~~~~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ error: Property 'toUppercase' does not exist on type 'string'.<\/span>\r\n    <span style=\"color: #148A14;\">\/\/        Did you mean 'toUpperCase'?<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>These assertion signatures are very similar to writing type predicate 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;\"><code><span style=\"color: #0000ff;\">function<\/span> isString(<span class=\"pl-v\">val<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span>)<span class=\"pl-k\">:<\/span> <span class=\"pl-en\">val<\/span> <span style=\"color: #0000ff;\">is<\/span> <span style=\"color: #0000ff;\">string<\/span> {\r\n    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">val<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> yell(<span class=\"pl-v\">str<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span>) {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-en\">isString<\/span>(<span class=\"pl-smi\">str<\/span>)) {\r\n        <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-smi\">str<\/span>.<span class=\"pl-en\">toUppercase<\/span>();\r\n    }\r\n    <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>Oops!<span class=\"pl-pds\">\"<\/span><\/span>;\r\n}<\/code><\/pre>\n<\/div>\n<p>And just like type predicate signatures, these assertion signatures are incredibly expressive. We can express some fairly sophisticated ideas with these.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> assertIsDefined&lt;<span style=\"color: #267F99;\">T<\/span>&gt;(<span class=\"pl-v\">val<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">T<\/span>)<span class=\"pl-k\">:<\/span> <span class=\"pl-en\">asserts<\/span> <span class=\"pl-en\">val<\/span> <span style=\"color: #0000ff;\">is<\/span> <span style=\"color: #267F99;\">NonNullable<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">val<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #0000ff;\">undefined<\/span> <span class=\"pl-k\">||<\/span> <span class=\"pl-smi\">val<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #0000ff;\">null<\/span>) {\r\n        <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">AssertionError<\/span>(\r\n            <span style=\"color: #a31515;\"><span class=\"pl-pds\">`<\/span>Expected 'val' to be defined, but received ${<span class=\"pl-smi\">val<\/span>}<span class=\"pl-pds\">`<\/span><\/span>\r\n        );\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>To read up more about assertion signatures, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/32695\">check out the original pull request<\/a>.<\/p>\n<h2 id=\"better-support-for-never-returning-functions\">Better Support for <code style=\"color: #a31515; font-size: 29px;\">never<\/code>-Returning Functions<\/h2>\n<p>As part of the work for assertion signatures, TypeScript needed to encode more about where and which functions were being called. This gave us the opportunity to expand support for another class of functions: functions that return <code>never<\/code>.<\/p>\n<p>The intent of any function that returns <code>never<\/code> is that it never returns. It indicates that an exception was thrown, a halting error condition occurred, or that the program exited. For example, <a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\/blob\/5299d372a220584e75a031c13b3d555607af13f8\/types\/node\/globals.d.ts#l874\"><code>process.exit(...)<\/code> in <code>@types\/node<\/code><\/a> is specified to return <code>never<\/code>.<\/p>\n<p>In order to ensure that a function never potentially returned <code>undefined<\/code> or effectively returned from all code paths, TypeScript needed some syntactic signal &#8211; either a <code>return<\/code> or <code>throw<\/code> at the end of a function. So users found themselves <code>return<\/code>-ing their failure functions.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> dispatch(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">SomeType<\/span> {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-en\">doThingWithString<\/span>(<span class=\"pl-smi\">x<\/span>);\r\n    }\r\n    <span style=\"color: #0000ff;\">else<\/span> <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>number<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-en\">doThingWithNumber<\/span>(<span class=\"pl-smi\">x<\/span>);\r\n    }\r\n    <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-c1\">process<\/span>.<span class=\"pl-c1\">exit<\/span>(<span style=\"color: #09885A;\">1<\/span>);\r\n}<\/code><\/pre>\n<\/div>\n<p>Now when these <code>never<\/code>-returning functions are called, TypeScript recognizes that they affect the control flow graph and accounts for them.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">function<\/span> dispatch(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">SomeType<\/span> {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>string<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-en\">doThingWithString<\/span>(<span class=\"pl-smi\">x<\/span>);\r\n    }\r\n    <span style=\"color: #0000ff;\">else<\/span> <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">typeof<\/span> <span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">===<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>number<span class=\"pl-pds\">\"<\/span><\/span>) {\r\n        <span style=\"color: #0000ff;\">return<\/span> <span class=\"pl-en\">doThingWithNumber<\/span>(<span class=\"pl-smi\">x<\/span>);\r\n    }\r\n    <span class=\"pl-c1\">process<\/span>.<span class=\"pl-c1\">exit<\/span>(<span style=\"color: #09885A;\">1<\/span>);\r\n}<\/code><\/pre>\n<\/div>\n<p>As with assertion functions, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/32695\">read up more at the same pull request<\/a>.<\/p>\n<h2 id=\"more-recursive-type-aliases\">(More) Recursive Type Aliases<\/h2>\n<p>Type aliases have always had a limitation in how they could be &#8220;recursively&#8221; referenced. The reason is that any use of a type alias needs to be able to substitute itself with whatever it aliases. In some cases, that&#8217;s not possible, so the compiler rejects certain recursive aliases like the following:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Foo<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">Foo<\/span>;<\/code><\/pre>\n<\/div>\n<p>This is a reasonable restriction because any use of <code>Foo<\/code> would need to be replaced with <code>Foo<\/code> which would need to be replaced with <code>Foo<\/code> which would need to be replaced with <code>Foo<\/code> which&#8230; well, hopefully you get the idea! In the end, there isn&#8217;t a type that makes sense in place of <code>Foo<\/code>.<\/p>\n<p>This is fairly <a href=\"https:\/\/en.wikipedia.org\/w\/index.php?title=Recursive_data_type&amp;oldid=913091335#in_type_synonyms\" rel=\"nofollow\">consistent with how other languages treat type aliases<\/a>, but it does give rise to some slightly surprising scenarios for how users leverage the feature. For example, in TypeScript 3.6 and prior, the following causes 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;\"><code><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">ValueOrArray<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">T<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">Array<\/span>&lt;<span style=\"color: #267F99;\">ValueOrArray<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt;&gt;;\r\n<span style=\"color: #148A14;\">\/\/   ~~~~~~~~~~~~<\/span>\r\n<span style=\"color: #148A14;\">\/\/ error: Type alias 'ValueOrArray' circularly references itself.<\/span><\/code><\/pre>\n<\/div>\n<p>This is strange because there is technically nothing wrong with any use users could always write what was effectively the same code by introducing an interface.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">ValueOrArray<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99;\">T<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">ArrayOfValueOrArray<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt;;\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">ArrayOfValueOrArray<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt; <span style=\"color: #0000ff;\">extends<\/span> <span class=\"pl-c1\">Array<\/span>&lt;<span style=\"color: #267F99;\">ValueOrArray<\/span>&lt;<span style=\"color: #267F99;\">T<\/span>&gt;&gt; {}<\/code><\/pre>\n<\/div>\n<p>Because interfaces (and other object types) introduce a level of indirection and their full structure doesn&#8217;t need to be eagerly built out, TypeScript has no problem working with this structure.<\/p>\n<p>But workaround of introducing the interface wasn&#8217;t intuitive for users. And in principle there really wasn&#8217;t anything wrong with the original version of <code>ValueOrArray<\/code> that used <code>Array<\/code> directly. If the compiler was a little bit &#8220;lazier&#8221; and only calculated the type arguments to <code>Array<\/code> when necessary, then TypeScript could express these correctly.<\/p>\n<p>That&#8217;s exactly what TypeScript 3.7 introduces. At the &#8220;top level&#8221; of a type alias, TypeScript will defer resolving type arguments to permit these patterns.<\/p>\n<p>This means that code like the following that was trying to represent JSON&#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;\"><code><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Json<\/span> <span class=\"pl-k\">=<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">boolean<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">null<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">JsonObject<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">JsonArray<\/span>;\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">JsonObject<\/span> {\r\n    [<span class=\"pl-v\">property<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Json<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">JsonArray<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span class=\"pl-c1\">Array<\/span>&lt;<span style=\"color: #267F99;\">Json<\/span>&gt; {}<\/code><\/pre>\n<\/div>\n<p>can finally be rewritten without helper interfaces.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Json<\/span> <span class=\"pl-k\">=<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">boolean<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">null<\/span>\r\n    <span class=\"pl-k\">|<\/span> { [<span class=\"pl-v\">property<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Json<\/span> }\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99;\">Json<\/span>[];<\/code><\/pre>\n<\/div>\n<p>This new relaxation also lets us recursively reference type aliases in tuples as well. The following code which used to error is now valid TypeScript 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;\"><code><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">VirtualNode<\/span> <span class=\"pl-k\">=<\/span>\r\n    <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>\r\n    <span class=\"pl-k\">|<\/span> [<span style=\"color: #0000ff;\">string<\/span>, { [<span class=\"pl-v\">key<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">any<\/span> }, ...<span style=\"color: #267F99;\">VirtualNode<\/span>[]];\r\n\r\n<span style=\"color: #0000ff;\">const<\/span> myNode<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">VirtualNode<\/span> <span class=\"pl-k\">=<\/span>\r\n    [<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>div<span class=\"pl-pds\">\"<\/span><\/span>, { id: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>parent<span class=\"pl-pds\">\"<\/span><\/span> },\r\n        [<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>div<span class=\"pl-pds\">\"<\/span><\/span>, { id: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>first-child<span class=\"pl-pds\">\"<\/span><\/span> }, <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>I'm the first child<span class=\"pl-pds\">\"<\/span><\/span>],\r\n        [<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>div<span class=\"pl-pds\">\"<\/span><\/span>, { id: <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>second-child<span class=\"pl-pds\">\"<\/span><\/span> }, <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>I'm the second child<span class=\"pl-pds\">\"<\/span><\/span>]\r\n    ];<\/code><\/pre>\n<\/div>\n<p>For more information, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/33050\">read up on the original pull request<\/a>.<\/p>\n<h2 id=\"--declaration-and---allowjs\"> <code style=\"color: #a31515; font-size: 29px;\">--declaration<\/code> and <code>--allowJs<\/code><\/h2>\n<p>The <code>--declaration<\/code> flag in TypeScript allows us to generate <code>.d.ts<\/code> files (declaration files) from source TypeScript files like <code>.ts<\/code> and <code>.tsx<\/code> files. These <code>.d.ts<\/code> files are important because they allow TypeScript to type-check against other projects without re-checking\/building the original source code. For the same reason, this setting is <em>required<\/em> when using project references.<\/p>\n<p>Unfortunately, <code>--declaration<\/code> didn&#8217;t work with settings like <code>--allowJs<\/code> to allow mixing TypeScript and JavaScript input files. This was a frustrating limitation because it meant users couldn&#8217;t use <code>--declaration<\/code> when migrating codebases, even if they were JSDoc-annotated. TypeScript 3.7 changes that, and allows the two features to be mixed!<\/p>\n<p>When using <code>allowJs<\/code>, TypeScript will use its best-effort understanding of JavaScript source code and save that to a <code>.d.ts<\/code> file in an equivalent representation. That includes all of its JSDoc smarts, so code like the following:<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\"> * <span class=\"pl-k\">@callback<\/span> <span style=\"color: #267F99;\">Job<\/span><\/span>\r\n<span style=\"color: #148A14;\"> * <span class=\"pl-k\">@returns<\/span> <span class=\"pl-en\">{void}<\/span><\/span>\r\n<span style=\"color: #148A14;\"> *\/<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/** Queues work *\/<\/span>\r\n<span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Worker<\/span> {\r\n    <span class=\"pl-en\">constructor<\/span>(<span class=\"pl-smi\">maxDepth<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A;\">10<\/span>) {\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">started<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #0000ff;\">false<\/span>;\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">depthLimit<\/span> <span class=\"pl-k\">=<\/span> maxDepth;\r\n        <span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\">         * NOTE: queued jobs may add more items to queue<\/span>\r\n<span style=\"color: #148A14;\">         * <span class=\"pl-k\">@type<\/span> <span class=\"pl-en\">{Job[]}<\/span><\/span>\r\n<span style=\"color: #148A14;\">         *\/<\/span>\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">queue<\/span> <span class=\"pl-k\">=<\/span> [];\r\n    }\r\n    <span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\">     * Adds a work item to the queue<\/span>\r\n<span style=\"color: #148A14;\">     * <span class=\"pl-k\">@param<\/span> <span class=\"pl-en\">{Job}<\/span> <span class=\"pl-smi\">work<\/span> <\/span>\r\n<span style=\"color: #148A14;\">     *\/<\/span>\r\n    <span class=\"pl-en\">push<\/span>(<span class=\"pl-smi\">work<\/span>) {\r\n        <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">queue<\/span>.<span class=\"pl-c1\">length<\/span> <span class=\"pl-k\">+<\/span> <span style=\"color: #09885A;\">1<\/span> <span class=\"pl-k\">&gt;<\/span> <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">depthLimit<\/span>) <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">Error<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>Queue full!<span class=\"pl-pds\">\"<\/span><\/span>);\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">queue<\/span>.<span class=\"pl-c1\">push<\/span>(work);\r\n    }\r\n    <span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\">     * Starts the queue if it has not yet started<\/span>\r\n<span style=\"color: #148A14;\">     *\/<\/span>\r\n    <span class=\"pl-en\">start<\/span>() {\r\n        <span style=\"color: #0000ff;\">if<\/span> (<span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">started<\/span>) <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">false<\/span>;\r\n        <span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">started<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #0000ff;\">true<\/span>;\r\n        <span style=\"color: #0000ff;\">while<\/span> (<span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">queue<\/span>.<span class=\"pl-c1\">length<\/span>) {\r\n            <span style=\"color: #148A14;\">\/** <span class=\"pl-k\">@type<\/span> <span class=\"pl-en\">{Job}<\/span> *\/<\/span>(<span style=\"color: #0000ff;\">this<\/span>.<span class=\"pl-smi\">queue<\/span>.<span class=\"pl-c1\">shift<\/span>())();\r\n        }\r\n        <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">true<\/span>;\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>will currently be transformed into the following implementation-less <code>.d.ts<\/code> 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;\"><code><span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\"> * <span class=\"pl-k\">@callback<\/span> <span style=\"color: #267F99;\">Job<\/span><\/span>\r\n<span style=\"color: #148A14;\"> * <span class=\"pl-k\">@returns<\/span> <span class=\"pl-en\">{void}<\/span><\/span>\r\n<span style=\"color: #148A14;\"> *\/<\/span>\r\n<span style=\"color: #148A14;\">\/** Queues work *\/<\/span>\r\n<span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #267F99;\">Worker<\/span> {\r\n    <span style=\"color: #0000ff;\">constructor<\/span>(<span class=\"pl-v\">maxDepth<\/span><span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>);\r\n    started<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>;\r\n    depthLimit<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n    <span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\">     * NOTE: queued jobs may add more items to queue<\/span>\r\n<span style=\"color: #148A14;\">     * <span class=\"pl-k\">@type<\/span> <span class=\"pl-en\">{Job[]}<\/span><\/span>\r\n<span style=\"color: #148A14;\">     *\/<\/span>\r\n    queue<span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Job<\/span>[];\r\n    <span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\">     * Adds a work item to the queue<\/span>\r\n<span style=\"color: #148A14;\">     * <span class=\"pl-k\">@param<\/span> <span class=\"pl-en\">{Job}<\/span> <span class=\"pl-smi\">work<\/span><\/span>\r\n<span style=\"color: #148A14;\">     *\/<\/span>\r\n    push(<span class=\"pl-v\">work<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">Job<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">void<\/span>;\r\n    <span style=\"color: #148A14;\">\/**<\/span>\r\n<span style=\"color: #148A14;\">     * Starts the queue if it has not yet started<\/span>\r\n<span style=\"color: #148A14;\">     *\/<\/span>\r\n    start()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>;\r\n}\r\n<span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267F99;\">Job<\/span> <span class=\"pl-k\">=<\/span> () <span class=\"pl-k\">=&gt;<\/span> <span style=\"color: #0000ff;\">void<\/span>;<\/code><\/pre>\n<\/div>\n<p>For more details, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/32372\">check out the original pull request<\/a>.<\/p>\n<h2 id=\"build-free-editing-with-project-references\">Build-Free Editing with Project References<\/h2>\n<p>TypeScript&#8217;s project references provide us with an easy way to break codebases up to give us faster compiles. Unfortunately, editing a project whose dependencies hadn&#8217;t been built (or whose output was out of date) meant that the editing experience wouldn&#8217;t work well.<\/p>\n<p>In TypeScript 3.7, when opening a project with dependencies, TypeScript will automatically use the source <code>.ts<\/code>\/<code>.tsx<\/code> files instead. This means projects using project references will now see an improved editing experience where semantic operations are up-to-date and &#8220;just work&#8221;. You can disable this behavior with the compiler option <code>disableSourceOfProjectReferenceRedirect<\/code> which may be appropriate when working in very large projects where this change may impact editing performance.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/32028\">read up more about this change by reading up on its pull request<\/a>.<\/p>\n<h2 id=\"uncalled-function-checks\">Uncalled Function Checks<\/h2>\n<p>A common and dangerous error is to forget to invoke a function, especially if the function has zero arguments or is named in a way that implies it might be a property rather than a function.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">User<\/span> {\r\n    isAdministrator()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>;\r\n    notify()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">void<\/span>;\r\n    doNotDisturb<span class=\"pl-k\">?<\/span>()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>;\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ later...<\/span>\r\n\r\n<span style=\"color: #148A14;\">\/\/ Broken code, do not use!<\/span>\r\n<span style=\"color: #0000ff;\">function<\/span> doAdminThing(<span class=\"pl-v\">user<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">User<\/span>) {\r\n    <span style=\"color: #148A14;\">\/\/ oops!<\/span>\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">user<\/span>.<span class=\"pl-smi\">isAdministrator<\/span>) {\r\n        <span class=\"pl-en\">sudo<\/span>();\r\n        <span class=\"pl-en\">editTheConfiguration<\/span>();\r\n    }\r\n    <span style=\"color: #0000ff;\">else<\/span> {\r\n        <span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #267F99;\">AccessDeniedError<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>User is not an admin<span class=\"pl-pds\">\"<\/span><\/span>);\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>Here, we forgot to call <code>isAdministrator<\/code>, and the code incorrectly allows non-adminstrator users to edit the configuration!<\/p>\n<p>In TypeScript 3.7, this is identified as a likely 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;\"><code><span style=\"color: #0000ff;\">function<\/span> doAdminThing(<span class=\"pl-v\">user<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">User<\/span>) {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">user<\/span>.<span class=\"pl-smi\">isAdministrator<\/span>) {\r\n    <span style=\"color: #148A14;\">\/\/  ~~~~~~~~~~~~~~~~~~~~<\/span>\r\n    <span style=\"color: #148A14;\">\/\/ error! 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><\/code><\/pre>\n<\/div>\n<p>This check is a breaking change, but for that reason the checks are very conservative. This error is only issued in <code>if<\/code> conditions, and it is not issued on optional properties, if <code>strictNullChecks<\/code> is off, or if the function is later called within the body of the <code>if<\/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;\"><code><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">User<\/span> {\r\n    isAdministrator()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>;\r\n    notify()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">void<\/span>;\r\n    doNotDisturb<span class=\"pl-k\">?<\/span>()<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">boolean<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> issueNotification(<span class=\"pl-v\">user<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">User<\/span>) {\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">user<\/span>.<span class=\"pl-smi\">doNotDisturb<\/span>) {\r\n        <span style=\"color: #148A14;\">\/\/ OK, property is optional<\/span>\r\n    }\r\n    <span style=\"color: #0000ff;\">if<\/span> (<span class=\"pl-smi\">user<\/span>.<span class=\"pl-smi\">notify<\/span>) {\r\n        <span style=\"color: #148A14;\">\/\/ OK, called the function<\/span>\r\n        <span class=\"pl-smi\">user<\/span>.<span class=\"pl-en\">notify<\/span>();\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>If you intended to test the function without calling it, you can correct the definition of it to include <code>undefined<\/code>\/<code>null<\/code>, or use <code>!!<\/code> to write something like <code>if (!!user.isAdministrator)<\/code> to indicate that the coercion is intentional.<\/p>\n<p>We owe a big thanks to GitHub user <a href=\"https:\/\/github.com\/jwbay\">@jwbay<\/a> who took the initiative to create a <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/32802\">proof-of-concept<\/a> and iterated to provide us with with <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/33178\">the current version<\/a>.<\/p>\n<h2 id=\"ts-nocheck-in-typescript-files\"><code style=\"color: #a31515; font-size: 29px;\">\/\/ @ts-nocheck<\/code> in TypeScript Files<\/h2>\n<p>TypeScript 3.7 allows us to add <code>\/\/ @ts-nocheck<\/code> comments to the top of TypeScript files to disable semantic checks. Historically this comment was only respected in JavaScript source files in the presence of <code>checkJs<\/code>, but we&#8217;ve expanded support to TypeScript files to make migrations easier for all users.<\/p>\n<h2 id=\"semicolon-formatter-option\">Semicolon Formatter Option<\/h2>\n<p>TypeScript&#8217;s built-in formatter now supports semicolon insertion and removal at locations where a trailing semicolon is optional due to JavaScript&#8217;s automatic semicolon insertion (ASI) rules. The setting is available now in <a href=\"https:\/\/code.visualstudio.com\/insiders\/\" rel=\"nofollow\">Visual Studio Code Insiders<\/a>, and will be available in Visual Studio 16.4 Preview 2 in the Tools Options menu.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2019\/10\/semicolons-options-3.7.png\" alt=\"New semicolon formatter option in VS Code\" width=\"833\" \/><\/p>\n<p>Choosing a value of &#8220;insert&#8221; or &#8220;remove&#8221; also affects the format of auto-imports, extracted types, and other generated code provided by TypeScript services. Leaving the setting on its default value of &#8220;ignore&#8221; makes generated code match the semicolon preference detected in the current file.<\/p>\n<h2 id=\"breaking-changes\">Breaking Changes<\/h2>\n<h3 id=\"dom-changes\">DOM Changes<\/h3>\n<p><a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/33627\">Types in <code>lib.dom.d.ts<\/code> have been updated<\/a>. These changes are largely correctness changes related to nullability, but impact will ultimately depend on your codebase.<\/p>\n<h3 id=\"function-truthy-checks\">Function Truthy Checks<\/h3>\n<p>As mentioned above, TypeScript now errors when functions appear to be uncalled within <code>if<\/code> statement conditions. An error is issued when a function type is checked in <code>if<\/code> conditions unless any of the following apply:<\/p>\n<ul>\n<li>the checked value comes from an optional property<\/li>\n<li><code>strictNullChecks<\/code> is disabled<\/li>\n<li>the function is later called within the body of the <code>if<\/code><\/li>\n<\/ul>\n<h3 id=\"local-and-imported-type-declarations-now-conflict\">Local and Imported Type Declarations Now Conflict<\/h3>\n<p>Due to a bug, the following construct was previously allowed 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;\"><code><span style=\"color: #148A14;\">\/\/ .\/someOtherModule.ts<\/span>\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">SomeType<\/span> {\r\n    y<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n}\r\n\r\n<span style=\"color: #148A14;\">\/\/ .\/myModule.ts<\/span>\r\n<span style=\"color: #0000ff;\">import<\/span> { <span class=\"pl-smi\">SomeType<\/span> } <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/someOtherModule<span class=\"pl-pds\">\"<\/span><\/span>;\r\n<span style=\"color: #0000ff;\">export<\/span> <span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267F99;\">SomeType<\/span> {\r\n    x<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">function<\/span> fn(<span class=\"pl-v\">arg<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99;\">SomeType<\/span>) {\r\n    <span class=\"pl-c1\">console<\/span>.<span class=\"pl-c1\">log<\/span>(<span class=\"pl-smi\">arg<\/span>.<span class=\"pl-c1\">x<\/span>); <span style=\"color: #148A14;\">\/\/ Error! 'x' doesn't exist on 'SomeType'<\/span>\r\n}<\/code><\/pre>\n<\/div>\n<p>Here, <code>SomeType<\/code> appears to originate in both the <code>import<\/code> declaration and the local <code>interface<\/code> declaration. Perhaps surprisingly, inside the module, <code>SomeType<\/code> refers exclusively to the <code>import<\/code>ed definition, and the local declaration <code>SomeType<\/code> is only usable when imported from another file. This is very confusing and our review of the very small number of cases of code like this in the wild showed that developers usually thought something different was happening.<\/p>\n<p>In TypeScript 3.7, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/31231\">this is now correctly identified as a duplicate identifier error<\/a>. The correct fix depends on the original intent of the author and should be addressed on a case-by-case basis. Usually, the naming conflict is unintentional and the best fix is to rename the imported type. If the intent was to augment the imported type, a proper module augmentation should be written instead.<\/p>\n<h3 id=\"api-changes\">API Changes<\/h3>\n<p>To enable the recursive type alias patterns described above, the <code>typeArguments<\/code> property has been removed from the <code>TypeReference<\/code> interface. Users should instead use the <code>getTypeArguments<\/code> function on <code>TypeChecker<\/code> instances.<\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>The final release of TypeScript 3.7 will be released in a couple of weeks, ideally with minimal changes! We&#8217;d love for you to try this RC and give us your feedback to make sure 3.7 works great for everyone. If you have any suggestions or run into any problems, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/new\/choose\">don&#8217;t hesitate to open an issue on our issue tracker<\/a>!<\/p>\n<p>Happy Hacking!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re pleased to announce TypeScript 3.7 RC, the release candidate of TypeScript 3.7. Between now and the final release, we expect no further changes except for 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 get [&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-2343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>We&#8217;re pleased to announce TypeScript 3.7 RC, the release candidate of TypeScript 3.7. Between now and the final release, we expect no further changes except for 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 get [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2343","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=2343"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2343\/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=2343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=2343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=2343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}