{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/release-notes/typescript-3-7.html","result":{"data":{"allSitePage":{"nodes":[{"path":"/dev-404-page/"},{"path":"/docs/handbook/advanced-types.html"},{"path":"/docs/handbook/basic-types.html"},{"path":"/docs/handbook/classes.html"},{"path":"/docs/handbook/compiler-options-in-msbuild.html"},{"path":"/docs/handbook/compiler-options.html"},{"path":"/docs/handbook/configuring-watch.html"},{"path":"/docs/handbook/declaration-merging.html"},{"path":"/docs/handbook/decorators.html"},{"path":"/docs/handbook/enums.html"},{"path":"/docs/handbook/functions.html"},{"path":"/docs/handbook/generics.html"},{"path":"/docs/handbook/integrating-with-build-tools.html"},{"path":"/docs/handbook/interfaces.html"},{"path":"/docs/handbook/iterators-and-generators.html"},{"path":"/docs/handbook/jsdoc-supported-types.html"},{"path":"/docs/handbook/jsx.html"},{"path":"/docs/handbook/literal-types.html"},{"path":"/docs/handbook/mixins.html"},{"path":"/docs/handbook/module-resolution.html"},{"path":"/docs/handbook/modules.html"},{"path":"/docs/handbook/namespaces-and-modules.html"},{"path":"/docs/handbook/namespaces.html"},{"path":"/docs/handbook/nightly-builds.html"},{"path":"/docs/handbook/project-references.html"},{"path":"/docs/handbook/symbols.html"},{"path":"/docs/handbook/"},{"path":"/docs/handbook/triple-slash-directives.html"},{"path":"/docs/handbook/type-checking-javascript-files.html"},{"path":"/docs/handbook/type-compatibility.html"},{"path":"/docs/handbook/type-inference.html"},{"path":"/docs/handbook/unions-and-intersections.html"},{"path":"/docs/handbook/utility-types.html"},{"path":"/docs/handbook/variable-declarations.html"},{"path":"/docs/handbook/writing-declaration-files.html"},{"path":"/docs/handbook/declaration-files/by-example.html"},{"path":"/docs/handbook/declaration-files/consumption.html"},{"path":"/docs/handbook/declaration-files/deep-dive.html"},{"path":"/docs/handbook/declaration-files/do-s-and-don-ts.html"},{"path":"/docs/handbook/declaration-files/introduction.html"},{"path":"/docs/handbook/declaration-files/library-structures.html"},{"path":"/docs/handbook/declaration-files/publishing.html"},{"path":"/docs/handbook/declaration-files/templates.html"},{"path":"/docs/handbook/release-notes/typescript-1-1.html"},{"path":"/docs/handbook/release-notes/typescript-1-3.html"},{"path":"/docs/handbook/release-notes/typescript-1-4.html"},{"path":"/docs/handbook/release-notes/typescript-1-5.html"},{"path":"/docs/handbook/release-notes/typescript-1-6.html"},{"path":"/docs/handbook/release-notes/typescript-1-7.html"},{"path":"/docs/handbook/release-notes/typescript-1-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-0.html"},{"path":"/docs/handbook/release-notes/typescript-2-2.html"},{"path":"/docs/handbook/release-notes/typescript-2-1.html"},{"path":"/docs/handbook/release-notes/typescript-2-3.html"},{"path":"/docs/handbook/release-notes/typescript-2-4.html"},{"path":"/docs/handbook/release-notes/typescript-2-5.html"},{"path":"/docs/handbook/release-notes/typescript-2-6.html"},{"path":"/docs/handbook/release-notes/typescript-2-7.html"},{"path":"/docs/handbook/release-notes/typescript-2-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-9.html"},{"path":"/docs/handbook/release-notes/typescript-3-0.html"},{"path":"/docs/handbook/release-notes/typescript-3-1.html"},{"path":"/docs/handbook/release-notes/typescript-3-2.html"},{"path":"/docs/handbook/release-notes/typescript-3-3.html"},{"path":"/docs/handbook/release-notes/typescript-3-4.html"},{"path":"/docs/handbook/release-notes/typescript-3-5.html"},{"path":"/docs/handbook/release-notes/typescript-3-6.html"},{"path":"/docs/handbook/release-notes/typescript-3-7.html"},{"path":"/docs/handbook/release-notes/typescript-3-8.html"},{"path":"/docs/handbook/asp-net-core.html"},{"path":"/docs/handbook/angular.html"},{"path":"/docs/handbook/dom-manipulation.html"},{"path":"/docs/handbook/gulp.html"},{"path":"/docs/handbook/migrating-from-javascript.html"},{"path":"/docs/handbook/react-&-webpack.html"},{"path":"/docs/handbook/react.html"},{"path":"/docs/handbook/typescript-in-5-minutes-func.html"},{"path":"/docs/handbook/typescript-in-5-minutes.html"},{"path":"/docs/handbook/typescript-in-5-minutes-oop.html"},{"path":"/docs/handbook/typescript-from-scratch.html"},{"path":"/docs/handbook/typescript-tooling-in-5-minutes.html"},{"path":"/docs/handbook/tsconfig-json.html"},{"path":"/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-class-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-function-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-d-ts.html"},{"path":"/docs/handbook/release-notes/overview.html"},{"path":"/tsconfig"},{"path":"/en/tsconfig"},{"path":"/ja/tsconfig"},{"path":"/vo/tsconfig"},{"path":"/play"},{"path":"/en/play"},{"path":"/es/play"},{"path":"/vo/play"},{"path":"/zh/play"},{"path":"/ja/play"},{"path":"/play/3-7/fixits/big-number-literals.ts"},{"path":"/play/3-7/fixits/const-to-let.ts"},{"path":"/play/3-7/fixits/infer-from-usage-changes.ts"},{"path":"/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/play/3-7/syntax-and-messaging/nullish-coalescing.ts"},{"path":"/play/3-7/syntax-and-messaging/optional-chaining.ts"},{"path":"/play/3-7/types-and-code-flow/assertion-functions.ts"},{"path":"/play/3-7/types-and-code-flow/recursive-type-references.ts"},{"path":"/play/3-7/types-and-code-flow/uncalled-function-checks.ts"},{"path":"/play/3-8/breaking-changes/checking-unions-with-index-signatures.ts"},{"path":"/play/3-8/jsdoc-improvements/accessibility-modifiers.js"},{"path":"/play/3-8/syntax-and-messaging/export-modules-from.ts"},{"path":"/play/3-8/syntax-and-messaging/private-class-fields.ts"},{"path":"/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/play/javascript/external-apis/typescript-with-node.js"},{"path":"/play/javascript/external-apis/typescript-with-web.js"},{"path":"/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/play/javascript/helping-with-javascript/errors.ts"},{"path":"/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/play/javascript/javascript-essentials/functions.ts"},{"path":"/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/play/javascript/modern-javascript/async-await.ts"},{"path":"/play/javascript/modern-javascript/immutability.ts"},{"path":"/play/javascript/modern-javascript/import-export.ts"},{"path":"/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/play/javascript/working-with-classes/classes-101.ts"},{"path":"/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/play/javascript/working-with-classes/mixins.ts"},{"path":"/play/javascript/working-with-classes/this.ts"},{"path":"/play/playground/config/javascript-playgrounds.js"},{"path":"/play/playground/config/new-compiler-defaults.ts"},{"path":"/play/playground/language/automatic-type-acquisition.ts"},{"path":"/play/playground/language/fixits.ts"},{"path":"/play/playground/tooling/mobile-support.ts"},{"path":"/play/playground/tooling/sharable-urls.ts"},{"path":"/play/playground/tooling/typescript-versions.ts"},{"path":"/play/typescript/language/soundness.ts"},{"path":"/play/typescript/language/structural-typing.ts"},{"path":"/play/typescript/language/type-guards.ts"},{"path":"/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/play/typescript/language-extensions/enums.ts"},{"path":"/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/play/typescript/meta-types/conditional-types.ts"},{"path":"/play/typescript/meta-types/discriminate-types.ts"},{"path":"/play/typescript/meta-types/indexed-types.ts"},{"path":"/play/typescript/meta-types/mapped-types.ts"},{"path":"/play/typescript/primitives/any.ts"},{"path":"/play/typescript/primitives/literals.ts"},{"path":"/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/play/typescript/primitives/unknown-and-never.ts"},{"path":"/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/play/typescript/type-primitives/nullable-types.ts"},{"path":"/play/typescript/type-primitives/tuples.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-node.js"},{"path":"/es/play/javascript/external-apis/typescript-with-web.js"},{"path":"/es/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/es/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/es/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/es/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/es/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/es/play/typescript/type-primitives/nullable-types.ts"},{"path":"/es/play/typescript/type-primitives/tuples.ts"},{"path":"/ja/play/typescript/language-extensions/enums.ts"},{"path":"/ja/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/ja/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/ja/play/typescript/primitives/any.ts"},{"path":"/ja/play/typescript/primitives/literals.ts"},{"path":"/ja/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/ja/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/vo/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/vo/play/javascript/javascript-essentials/functions.ts"},{"path":"/vo/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/vo/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-node.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-web.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/zh/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/zh/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/zh/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/zh/play/javascript/helping-with-javascript/errors.ts"},{"path":"/zh/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/zh/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/zh/play/javascript/javascript-essentials/functions.ts"},{"path":"/zh/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/zh/play/javascript/modern-javascript/import-export.ts"},{"path":"/zh/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/zh/play/javascript/working-with-classes/classes-101.ts"},{"path":"/zh/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/zh/play/javascript/working-with-classes/mixins.ts"},{"path":"/zh/play/javascript/working-with-classes/this.ts"},{"path":"/zh/play/playground/config/javascript-playgrounds.js"},{"path":"/zh/play/playground/config/new-compiler-defaults.ts"},{"path":"/zh/play/playground/language/automatic-type-acquisition.ts"},{"path":"/zh/play/playground/language/fixits.ts"},{"path":"/zh/play/playground/tooling/mobile-support.ts"},{"path":"/zh/play/playground/tooling/sharable-urls.ts"},{"path":"/zh/play/playground/tooling/typescript-versions.ts"},{"path":"/zh/play/typescript/language/soundness.ts"},{"path":"/zh/play/typescript/language/structural-typing.ts"},{"path":"/zh/play/typescript/language/type-guards.ts"},{"path":"/zh/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/zh/play/typescript/language-extensions/enums.ts"},{"path":"/zh/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/zh/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/zh/play/typescript/meta-types/conditional-types.ts"},{"path":"/zh/play/typescript/meta-types/discriminate-types.ts"},{"path":"/zh/play/typescript/meta-types/indexed-types.ts"},{"path":"/zh/play/typescript/meta-types/mapped-types.ts"},{"path":"/zh/play/typescript/primitives/any.ts"},{"path":"/zh/play/typescript/primitives/literals.ts"},{"path":"/zh/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/zh/play/typescript/primitives/unknown-and-never.ts"},{"path":"/zh/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/zh/play/typescript/type-primitives/nullable-types.ts"},{"path":"/zh/play/typescript/type-primitives/tuples.ts"},{"path":"/zh/play/javascript/modern-javascript/immutability.ts"},{"path":"/zh/play/javascript/modern-javascript/async-await.ts"},{"path":"/zh/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/community"},{"path":"/es/community"},{"path":"/ja/community"},{"path":"/vo/community"},{"path":"/zh/community"},{"path":"/download"},{"path":"/es/download"},{"path":"/ja/download"},{"path":"/vo/download"},{"path":"/zh/download"},{"path":"/empty"},{"path":"/es/empty"},{"path":"/ja/empty"},{"path":"/vo/empty"},{"path":"/zh/empty"},{"path":"/"},{"path":"/es/"},{"path":"/ja/"},{"path":"/vo/"},{"path":"/zh/"},{"path":"/tools"},{"path":"/es/tools"},{"path":"/ja/tools"},{"path":"/vo/tools"},{"path":"/zh/tools"},{"path":"/why-create-typescript"},{"path":"/es/why-create-typescript"},{"path":"/ja/why-create-typescript"},{"path":"/vo/why-create-typescript"},{"path":"/zh/why-create-typescript"},{"path":"/docs/home"},{"path":"/es/docs/home"},{"path":"/ja/docs/home"},{"path":"/vo/docs/home"},{"path":"/zh/docs/home"},{"path":"/dev/playground-plugins/"},{"path":"/dev/sandbox/"},{"path":"/dev/twoslash/"},{"path":"/dev/typescript-vfs/"}]},"markdownRemark":{"id":"630dcd47-c035-5bef-a5d2-1be27d5cd564","excerpt":"Optional Chaining Playground Optional chaining is issue #16 on our issue tracker. For context, there have been over 23,000 issues on the TypeScript issue…","html":"<h2 id=\"optional-chaining\" style=\"position:relative;\"><a href=\"#optional-chaining\" aria-label=\"optional chaining permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Optional Chaining</h2>\n<p><a href=\"/play/#example/optional-chaining\">Playground</a></p>\n<p>Optional chaining is <a href=\"https://github.com/microsoft/TypeScript/issues/16\">issue #16</a> on our issue tracker. For context, there have been over 23,000 issues on the TypeScript issue tracker since then.</p>\n<p>At its core, optional chaining lets us write code where TypeScript can immediately stop running some expressions if we run into a <code>null</code> or <code>undefined</code>.\nThe star of the show in optional chaining is the new <code>?.</code> operator for <em>optional property accesses</em>.\nWhen we write code like</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = foo?.bar.baz();</span></code></div></pre>\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’re doing and just return <code>undefined</code>.”</p>\n<p>More plainly, that code snippet is the same as writing the following.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = foo === </span><span style=\"color: #0000FF\">null</span><span style=\"color: #000000\"> || foo === </span><span style=\"color: #0000FF\">undefined</span><span style=\"color: #000000\"> ? </span><span style=\"color: #0000FF\">undefined</span><span style=\"color: #000000\"> : foo.bar.baz();</span></code></div></pre>\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>.\nLikewise, if <code>baz</code> is <code>null</code> or <code>undefined</code>, we’ll hit an error at the call site.\n<code>?.</code> only checks for whether the value on the <em>left</em> of it is <code>null</code> or <code>undefined</code> - not any of the subsequent properties.</p>\n<p>You might find yourself using <code>?.</code> to replace a lot of code that performs repetitive nullish checks using the <code>&#x26;&#x26;</code> operator.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// Before</span>\n<span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (foo && foo.bar && foo.bar.baz) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// After-ish</span>\n<span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (foo?.bar?.baz) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Keep in mind that <code>?.</code> acts differently than those <code>&#x26;&#x26;</code> operations since <code>&#x26;&#x26;</code> will act specially on “falsy” values (e.g. the empty string, <code>0</code>, <code>NaN</code>, and, well, <code>false</code>), but this is an intentional feature of the construct.\nIt doesn’t short-circuit on valid data like <code>0</code> or empty strings.</p>\n<p>Optional chaining also includes two other operations.\nFirst there’s the <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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * Get the first element of the array if we have an array.</span>\n<span style=\"color: #008000\"> * Otherwise return undefined.</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> tryGetFirstElement&lt;T&gt;(arr?: T[]) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> arr?.[</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// equivalent to</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//   return (arr === null || arr === undefined) ?</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//       undefined :</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//       arr[0];</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>There’s also <em>optional call</em>, which allows us to conditionally call expressions if they’re not <code>null</code> or <code>undefined</code>.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">async</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> makeRequest(url: string, log?: (msg: string) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void) {</span>\n<span style=\"color: #000000\">  log?.(</span><span style=\"color: #A31515\">`Request started at </span><span style=\"color: #0000FF\">${new</span><span style=\"color: #A31515\"> Date().toISOString()</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// roughly equivalent to</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//   if (log != null) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//       log(`Request started at ${new Date().toISOString()}`);</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//   }</span>\n\n<span style=\"color: #000000\">  const result = (</span><span style=\"color: #0000FF\">await</span><span style=\"color: #000000\"> fetch(url)).json();</span>\n\n<span style=\"color: #000000\">  log?.(</span><span style=\"color: #A31515\">`Request finished at at </span><span style=\"color: #0000FF\">${new</span><span style=\"color: #A31515\"> Date().toISOString()</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">);</span>\n\n<span style=\"color: #000000\">  return result;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>The “short-circuiting” behavior that optional chains have is limited property accesses, calls, element accesses - it doesn’t expand any further out from these expressions.\nIn other words,</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> result = foo?.bar / someComputation();</span></code></div></pre>\n<p>doesn’t stop the division or <code>someComputation()</code> call from occurring.\nIt’s equivalent to</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> temp = foo === </span><span style=\"color: #0000FF\">null</span><span style=\"color: #000000\"> || foo === </span><span style=\"color: #0000FF\">undefined</span><span style=\"color: #000000\"> ? </span><span style=\"color: #0000FF\">undefined</span><span style=\"color: #000000\"> : foo.bar;</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> result = temp / someComputation();</span></code></div></pre>\n<p>That might result in dividing <code>undefined</code>, which is why in <code>strictNullChecks</code>, the following is an error.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> barPercentage(foo?: { bar: number }) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> foo?.bar / </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//     ~~~~~~~~</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Error: Object is possibly undefined.</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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\" style=\"position:relative;\"><a href=\"#nullish-coalescing\" aria-label=\"nullish coalescing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nullish Coalescing</h2>\n<p><a href=\"/play/#example/nullish-coalescing\">Playground</a></p>\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 involved with championing in TC39.</p>\n<p>You can think of this feature - the <code>??</code> operator - as a way to “fall back” to a default value when dealing with <code>null</code> or <code>undefined</code>.\nWhen we write code like</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = foo ?? bar();</span></code></div></pre>\n<p>this is a new way to say that the value <code>foo</code> will be used when it’s “present”;\nbut when it’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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = foo !== </span><span style=\"color: #0000FF\">null</span><span style=\"color: #000000\"> && foo !== </span><span style=\"color: #0000FF\">undefined</span><span style=\"color: #000000\"> ? foo : bar();</span></code></div></pre>\n<p>The <code>??</code> operator can replace uses of <code>||</code> when trying to use a default value.\nFor 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\"><code>localStorage</code></a> (if it ever was);\nhowever, it has a bug because it uses <code>||</code>.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> initializeAudio() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> volume = localStorage.volume || </span><span style=\"color: #09835A\">0.5</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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.\n<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!\nFor 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\" style=\"position:relative;\"><a href=\"#assertion-functions\" aria-label=\"assertion functions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Assertion Functions</h2>\n<p><a href=\"/play/#example/assertion-functions\">Playground</a></p>\n<p>There’s a specific set of functions that <code>throw</code> an error if something unexpected happened.\nThey’re called “assertion” functions.\nAs an example, Node.js has a dedicated function for this called <code>assert</code>.</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #000000\">assert(someValue === </span><span style=\"color: #09835A\">42</span><span style=\"color: #000000\">);</span></code></div></pre>\n<p>In this example if <code>someValue</code> isn’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.\nFor example,</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> multiply(x, y) {</span>\n<span style=\"color: #000000\">  assert(</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> x === </span><span style=\"color: #A31515\">\"number\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">  assert(</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> y === </span><span style=\"color: #A31515\">\"number\"</span><span style=\"color: #000000\">);</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> x * y;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Unfortunately in TypeScript these checks could never be properly encoded.\nFor loosely-typed code this meant TypeScript was checking less, and for slightly conservative code it often forced users to use type assertions.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> yell(str) {</span>\n<span style=\"color: #000000\">  assert(</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> str === </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">);</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> str.toUppercase();</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Oops! We misspelled 'toUpperCase'.</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Would be great if TypeScript still caught this!</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>The alternative was to instead rewrite the code so that the language could analyze it, but this isn’t convenient.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> yell(str) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> str !== </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> TypeError(</span><span style=\"color: #A31515\">\"str should have been a string.\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Error caught!</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> str.toUppercase();</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Ultimately the goal of TypeScript is to type existing JavaScript constructs in the least disruptive way.\nFor that reason, TypeScript 3.7 introduces a new concept called “assertion signatures” which model these assertion functions.</p>\n<p>The first type of assertion signature models the way that Node’s <code>assert</code> function works.\nIt ensures that whatever condition is being checked must be true for the remainder of the containing scope.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> assert(condition: any, msg?: string): asserts condition {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (!condition) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> AssertionError(msg);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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).\nThat means that for the rest of the scope, that condition must be truthy.\nAs an example, using this assertion function means we <em>do</em> catch our original <code>yell</code> example.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> yell(str) {</span>\n<span style=\"color: #000000\">  assert(</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> str === </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">);</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> str.toUppercase();</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//         ~~~~~~~~~~~</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// error: Property 'toUppercase' does not exist on type 'string'.</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//        Did you mean 'toUpperCase'?</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> assert(condition: any, msg?: string): asserts condition {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (!condition) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> AssertionError(msg);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>The other type of assertion signature doesn’t check for a condition, but instead tells TypeScript that a specific variable or property has a different type.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> assertIsString(val: any): asserts val </span><span style=\"color: #0000FF\">is</span><span style=\"color: #000000\"> string {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> val !== </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> AssertionError(</span><span style=\"color: #A31515\">\"Not a string!\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> yell(str: any) {</span>\n<span style=\"color: #000000\">  assertIsString(str);</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Now TypeScript knows that 'str' is a 'string'.</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> str.toUppercase();</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//         ~~~~~~~~~~~</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// error: Property 'toUppercase' does not exist on type 'string'.</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//        Did you mean 'toUpperCase'?</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>These assertion signatures are very similar to writing type predicate signatures:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> isString(val: any): val </span><span style=\"color: #0000FF\">is</span><span style=\"color: #000000\"> string {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> val === </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> yell(str: any) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (isString(str)) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> str.toUppercase();</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"Oops!\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>And just like type predicate signatures, these assertion signatures are incredibly expressive.\nWe can express some fairly sophisticated ideas with these.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> assertIsDefined&lt;T&gt;(val: T): asserts val </span><span style=\"color: #0000FF\">is</span><span style=\"color: #000000\"> NonNullable&lt;T&gt; {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (val === </span><span style=\"color: #0000FF\">undefined</span><span style=\"color: #000000\"> || val === </span><span style=\"color: #0000FF\">null</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> AssertionError(</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #A31515\">`Expected 'val' to be defined, but received </span><span style=\"color: #0000FF\">${</span><span style=\"color: #A31515\">val</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span>\n<span style=\"color: #000000\">    );</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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\" style=\"position:relative;\"><a href=\"#better-support-for-never-returning-functions\" aria-label=\"better support for never returning functions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Better Support for <code>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.\nThis 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.\nIt indicates that an exception was thrown, a halting error condition occurred, or that the program exited.\nFor 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 - either a <code>return</code> or <code>throw</code> at the end of a function.\nSo users found themselves <code>return</code>-ing their failure functions.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> dispatch(x: string | number): SomeType {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> x === </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> doThingWithString(x);</span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> x === </span><span style=\"color: #A31515\">\"number\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> doThingWithNumber(x);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> process.exit(</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> dispatch(x: string | number): SomeType {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> x === </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> doThingWithString(x);</span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> x === </span><span style=\"color: #A31515\">\"number\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> doThingWithNumber(x);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  process.exit(</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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\" style=\"position:relative;\"><a href=\"#more-recursive-type-aliases\" aria-label=\"more recursive type aliases permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>(More) Recursive Type Aliases</h2>\n<p><a href=\"/play/#example/recursive-type-references\">Playground</a></p>\n<p>Type aliases have always had a limitation in how they could be “recursively” referenced.\nThe reason is that any use of a type alias needs to be able to substitute itself with whatever it aliases.\nIn some cases, that’s not possible, so the compiler rejects certain recursive aliases like the following:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Foo = Foo;</span></code></div></pre>\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… well, hopefully you get the idea!\nIn the end, there isn’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&#x26;oldid=913091335#in_type_synonyms\">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.\nFor example, in TypeScript 3.6 and prior, the following causes an error.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> ValueOrArray&lt;T&gt; = T | Array&lt;ValueOrArray&lt;T&gt;&gt;;</span>\n<span style=\"color: #008000\">//   ~~~~~~~~~~~~</span>\n<span style=\"color: #008000\">// error: Type alias 'ValueOrArray' circularly references itself.</span></code></div></pre>\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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> ValueOrArray&lt;T&gt; = T | ArrayOfValueOrArray&lt;T&gt;;</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> ArrayOfValueOrArray&lt;T&gt; </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Array&lt;ValueOrArray&lt;T&gt;&gt; {}</span></code></div></pre>\n<p>Because interfaces (and other object types) introduce a level of indirection and their full structure doesn’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’t intuitive for users.\nAnd in principle there really wasn’t anything wrong with the original version of <code>ValueOrArray</code> that used <code>Array</code> directly.\nIf the compiler was a little bit “lazier” and only calculated the type arguments to <code>Array</code> when necessary, then TypeScript could express these correctly.</p>\n<p>That’s exactly what TypeScript 3.7 introduces.\nAt the “top level” 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…</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Json = string | number | boolean | null | JsonObject | JsonArray;</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> JsonObject {</span>\n<span style=\"color: #000000\">  [property: string]: Json;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> JsonArray </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Array&lt;Json&gt; {}</span></code></div></pre>\n<p>can finally be rewritten without helper interfaces.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Json =</span>\n<span style=\"color: #000000\">  | string</span>\n<span style=\"color: #000000\">  | number</span>\n<span style=\"color: #000000\">  | boolean</span>\n<span style=\"color: #000000\">  | null</span>\n<span style=\"color: #000000\">  | { [property: string]: Json }</span>\n<span style=\"color: #000000\">  | Json[];</span></code></div></pre>\n<p>This new relaxation also lets us recursively reference type aliases in tuples as well.\nThe following code which used to error is now valid TypeScript code.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> VirtualNode = string | [string, { [key: string]: any }, ...VirtualNode[]];</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> myNode: VirtualNode = [</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #A31515\">\"div\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  { id: </span><span style=\"color: #A31515\">\"parent\"</span><span style=\"color: #000000\"> },</span>\n<span style=\"color: #000000\">  [</span><span style=\"color: #A31515\">\"div\"</span><span style=\"color: #000000\">, { id: </span><span style=\"color: #A31515\">\"first-child\"</span><span style=\"color: #000000\"> }, </span><span style=\"color: #A31515\">\"I'm the first child\"</span><span style=\"color: #000000\">],</span>\n<span style=\"color: #000000\">  [</span><span style=\"color: #A31515\">\"div\"</span><span style=\"color: #000000\">, { id: </span><span style=\"color: #A31515\">\"second-child\"</span><span style=\"color: #000000\"> }, </span><span style=\"color: #A31515\">\"I'm the second child\"</span><span style=\"color: #000000\">]</span>\n<span style=\"color: #000000\">];</span></code></div></pre>\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\" style=\"position:relative;\"><a href=\"#--declaration-and---allowjs\" aria-label=\"  declaration and   allowjs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>--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 TypeScript source files (i.e. <code>.ts</code> and <code>.tsx</code> files).\nThese <code>.d.ts</code> files are important for a couple of reasons.</p>\n<p>First of all, they’re important because they allow TypeScript to type-check against other projects without re-checking the original source code.\nThey’re also important because they allow TypeScript to interoperate with existing JavaScript libraries that weren’t built with TypeScript in mind.\nFinally, a benefit that is often underappreciated: both TypeScript <em>and</em> JavaScript users can benefit from these files when using editors powered by TypeScript to get things like better auto-completion.</p>\n<p>Unfortunately, <code>--declaration</code> didn’t work with the <code>--allowJs</code> flag which allows mixing TypeScript and JavaScript input files.\nThis was a frustrating limitation because it meant users couldn’t use the <code>--declaration</code> flag when migrating codebases, even if they were JSDoc-annotated.\nTypeScript 3.7 changes that, and allows the two options to be used together!</p>\n<p>The most impactful outcome of this feature might a bit subtle: with TypeScript 3.7, users can write libraries in JSDoc annotated JavaScript and support TypeScript users.</p>\n<p>The way that this works is that when using <code>allowJs</code>, TypeScript has some best-effort analyses to understand common JavaScript patterns; however, the way that some patterns are expressed in JavaScript don’t necessarily look like their equivalents in TypeScript.\nWhen <code>declaration</code> emit is turned on, TypeScript figures out the best way to transform JSDoc comments and CommonJS exports into valid type declarations and the like in the output <code>.d.ts</code> files.</p>\n<p>As an example, the following code snippet</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> assert = require(</span><span style=\"color: #A31515\">\"assert\"</span><span style=\"color: #000000\">);</span>\n\n<span style=\"color: #000000\">module.exports.blurImage = blurImage;</span>\n\n<span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * Produces a blurred image from an input buffer.</span>\n<span style=\"color: #008000\"> *</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> input {Uint8Array}</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> width {number}</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> height {number}</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> blurImage(input, width, height) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> numPixels = width * height * </span><span style=\"color: #09835A\">4</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  assert(input.length === numPixels);</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> result = </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> Uint8Array(numPixels);</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// TODO</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> result;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Will produce a <code>.d.ts</code> file like</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * Produces a blurred image from an input buffer.</span>\n<span style=\"color: #008000\"> *</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> input {Uint8Array}</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> width {number}</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> height {number}</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> blurImage(</span>\n<span style=\"color: #000000\">  input: Uint8Array,</span>\n<span style=\"color: #000000\">  width: number,</span>\n<span style=\"color: #000000\">  height: number</span>\n<span style=\"color: #000000\">): Uint8Array;</span></code></div></pre>\n<p>This can go beyond basic functions with <code>@param</code> tags too, where the following example:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@callback</span><span style=\"color: #008000\"> Job</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@returns</span><span style=\"color: #008000\"> {void}</span>\n<span style=\"color: #008000\"> */</span>\n\n<span style=\"color: #008000\">/** Queues work */</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Worker {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(maxDepth = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.started = </span><span style=\"color: #0000FF\">false</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.depthLimit = maxDepth;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\">     * NOTE: queued jobs may add more items to queue</span>\n<span style=\"color: #008000\">     * </span><span style=\"color: #0000FF\">@type</span><span style=\"color: #008000\"> {Job[]}</span>\n<span style=\"color: #008000\">     */</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.queue = [];</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\">   * Adds a work item to the queue</span>\n<span style=\"color: #008000\">   * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> {Job} work</span>\n<span style=\"color: #008000\">   */</span>\n<span style=\"color: #000000\">  push(work) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.queue.length + </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> &gt; </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.depthLimit) </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> Error(</span><span style=\"color: #A31515\">\"Queue full!\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.queue.push(work);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\">   * Starts the queue if it has not yet started</span>\n<span style=\"color: #008000\">   */</span>\n<span style=\"color: #000000\">  start() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.started) </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">false</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.started = </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">while</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.queue.length) {</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #008000\">/** </span><span style=\"color: #0000FF\">@type</span><span style=\"color: #008000\"> {Job} */</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.queue.shift())();</span>\n<span style=\"color: #000000\">    }</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>will be transformed into the following <code>.d.ts</code> file:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@callback</span><span style=\"color: #008000\"> Job</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@returns</span><span style=\"color: #008000\"> {void}</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #008000\">/** Queues work */</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Worker {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(maxDepth?: number);</span>\n<span style=\"color: #000000\">  started: boolean;</span>\n<span style=\"color: #000000\">  depthLimit: number;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\">   * NOTE: queued jobs may add more items to queue</span>\n<span style=\"color: #008000\">   * </span><span style=\"color: #0000FF\">@type</span><span style=\"color: #008000\"> {Job[]}</span>\n<span style=\"color: #008000\">   */</span>\n<span style=\"color: #000000\">  queue: Job[];</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\">   * Adds a work item to the queue</span>\n<span style=\"color: #008000\">   * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> {Job} work</span>\n<span style=\"color: #008000\">   */</span>\n<span style=\"color: #000000\">  push(work: Job): void;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\">   * Starts the queue if it has not yet started</span>\n<span style=\"color: #008000\">   */</span>\n<span style=\"color: #000000\">  start(): boolean;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Job = () </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void;</span></code></div></pre>\n<p>Note that when using these flags together, TypeScript doesn’t necessarily have to downlevel <code>.js</code> files.\nIf you simply want TypeScript to create <code>.d.ts</code> files, you can use the <code>--emitDeclarationOnly</code> compiler option.</p>\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=\"the-usedefineforclassfields-flag-and-the-declare-property-modifier\" style=\"position:relative;\"><a href=\"#the-usedefineforclassfields-flag-and-the-declare-property-modifier\" aria-label=\"the usedefineforclassfields flag and the declare property modifier permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <code>useDefineForClassFields</code> Flag and The <code>declare</code> Property Modifier</h2>\n<p>Back when TypeScript implemented public class fields, we assumed to the best of our abilities that the following code</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">  foo = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  bar: string;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>would be equivalent to a similar assignment within a constructor body.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.foo = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Unfortunately, while this seemed to be the direction that the proposal moved towards in its earlier days, there is an extremely strong chance that public class fields will be standardized differently.\nInstead, the original code sample might need to de-sugar to something closer to the following:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">    Object.defineProperty(</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"foo\"</span><span style=\"color: #000000\">, {</span>\n<span style=\"color: #000000\">      enumerable: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">      configurable: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">      writable: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">      value: </span><span style=\"color: #09835A\">100</span>\n<span style=\"color: #000000\">    });</span>\n<span style=\"color: #000000\">    Object.defineProperty(</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\">, {</span>\n<span style=\"color: #000000\">      enumerable: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">      configurable: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">      writable: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">      value: </span><span style=\"color: #0000FF\">void</span><span style=\"color: #000000\"> </span><span style=\"color: #09835A\">0</span>\n<span style=\"color: #000000\">    });</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>While TypeScript 3.7 isn’t changing any existing emit by default, we’ve been rolling out changes incrementally to help users mitigate potential future breakage.\nWe’ve provided a new flag called <code>useDefineForClassFields</code> to enable this emit mode with some new checking logic.</p>\n<p>The two biggest changes are the following:</p>\n<ul>\n<li>Declarations are initialized with <code>Object.defineProperty</code>.</li>\n<li>Declarations are <em>always</em> initialized to <code>undefined</code>, even if they have no initializer.</li>\n</ul>\n<p>This can cause quite a bit of fallout for existing code that use inheritance. First of all, <code>set</code> accessors from base classes won’t get triggered - they’ll be completely overwritten.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Base {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">set</span><span style=\"color: #000000\"> data(value: string) {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">\"data changed to \"</span><span style=\"color: #000000\"> + value);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Derived </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Base {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// No longer triggers a 'console.log'</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// when using 'useDefineForClassFields'.</span>\n<span style=\"color: #000000\">  data = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Secondly, using class fields to specialize properties from base classes also won’t work.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Animal {</span>\n<span style=\"color: #000000\">  animalStuff: any;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Dog </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Animal {</span>\n<span style=\"color: #000000\">  dogStuff: any;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> AnimalHouse {</span>\n<span style=\"color: #000000\">  resident: Animal;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(animal: Animal) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.resident = animal;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> DogHouse </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> AnimalHouse {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Initializes 'resident' to 'undefined'</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// after the call to 'super()' when</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// using 'useDefineForClassFields'!</span>\n<span style=\"color: #000000\">  resident: Dog;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(dog: Dog) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">super</span><span style=\"color: #000000\">(dog);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>What these two boil down to is that mixing properties with accessors is going to cause issues, and so will re-declaring properties with no initializers.</p>\n<p>To detect the issue around accessors, TypeScript 3.7 will now emit <code>get</code>/<code>set</code> accessors in <code>.d.ts</code> files so that in TypeScript can check for overridden accessors.</p>\n<p>Code that’s impacted by the class fields change can get around the issue by converting field initializers to assignments in constructor bodies.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Base {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">set</span><span style=\"color: #000000\"> data(value: string) {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">\"data changed to \"</span><span style=\"color: #000000\"> + value);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Derived </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Base {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">    data = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>To help mitigate the second issue, you can either add an explicit initializer or add a <code>declare</code> modifier to indicate that a property should have no emit.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Animal {</span>\n<span style=\"color: #000000\">  animalStuff: any;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Dog </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Animal {</span>\n<span style=\"color: #000000\">  dogStuff: any;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> AnimalHouse {</span>\n<span style=\"color: #000000\">  resident: Animal;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(animal: Animal) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.resident = animal;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> DogHouse </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> AnimalHouse {</span>\n<span style=\"color: #000000\">  declare resident: Dog;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">//  ^^^^^^^</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// 'resident' now has a 'declare' modifier,</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// and won't produce any output code.</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(dog: Dog) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">super</span><span style=\"color: #000000\">(dog);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Currently <code>useDefineForClassFields</code> is only available when targeting ES5 and upwards, since <code>Object.defineProperty</code> doesn’t exist in ES3.\nTo achieve similar checking for issues, you can create a seperate project that targets ES5 and uses <code>--noEmit</code> to avoid a full build.</p>\n<p>For more information, you can <a href=\"https://github.com/microsoft/TypeScript/pull/33509\">take a look at the original pull request for these changes</a>.</p>\n<p>We strongly encourage users to try the <code>useDefineForClassFields</code> flag and report back on our issue tracker or in the comments below.\nThis includes feedback on difficulty of adopting the flag so we can understand how we can make migration easier.</p>\n<h2 id=\"build-free-editing-with-project-references\" style=\"position:relative;\"><a href=\"#build-free-editing-with-project-references\" aria-label=\"build free editing with project references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Build-Free Editing with Project References</h2>\n<p>TypeScript’s project references provide us with an easy way to break codebases up to give us faster compiles.\nUnfortunately, editing a project whose dependencies hadn’t been built (or whose output was out of date) meant that the editing experience wouldn’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.\nThis means projects using project references will now see an improved editing experience where semantic operations are up-to-date and “just work”.\nYou 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\" style=\"position:relative;\"><a href=\"#uncalled-function-checks\" aria-label=\"uncalled function checks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> User {</span>\n<span style=\"color: #000000\">  isAdministrator(): boolean;</span>\n<span style=\"color: #000000\">  notify(): void;</span>\n<span style=\"color: #000000\">  doNotDisturb?(): boolean;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// later...</span>\n\n<span style=\"color: #008000\">// Broken code, do not use!</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> doAdminThing(user: User) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// oops!</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (user.isAdministrator) {</span>\n<span style=\"color: #000000\">    sudo();</span>\n<span style=\"color: #000000\">    editTheConfiguration();</span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> AccessDeniedError(</span><span style=\"color: #A31515\">\"User is not an admin\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> doAdminThing(user: User) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (user.isAdministrator) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">//  ~~~~~~~~~~~~~~~~~~~~</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// error! This condition will always return true since the function is always defined.</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">//        Did you mean to call it instead?</span></code></div></pre>\n<p>This check is a breaking change, but for that reason the checks are very conservative.\nThis 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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> User {</span>\n<span style=\"color: #000000\">  isAdministrator(): boolean;</span>\n<span style=\"color: #000000\">  notify(): void;</span>\n<span style=\"color: #000000\">  doNotDisturb?(): boolean;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> issueNotification(user: User) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (user.doNotDisturb) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// OK, property is optional</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (user.notify) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// OK, called the function</span>\n<span style=\"color: #000000\">    user.notify();</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\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\" style=\"position:relative;\"><a href=\"#-ts-nocheck-in-typescript-files\" aria-label=\" ts nocheck in typescript files permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>// @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.\nHistorically this comment was only respected in JavaScript source files in the presence of <code>checkJs</code>, but we’ve expanded support to TypeScript files to make migrations easier for all users.</p>\n<h2 id=\"semicolon-formatter-option\" style=\"position:relative;\"><a href=\"#semicolon-formatter-option\" aria-label=\"semicolon formatter option permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Semicolon Formatter Option</h2>\n<p>TypeScript’s built-in formatter now supports semicolon insertion and removal at locations where a trailing semicolon is optional due to JavaScript’s automatic semicolon insertion (ASI) rules. The setting is available now in <a href=\"https://code.visualstudio.com/insiders/\">Visual Studio Code Insiders</a>, and will be available in Visual Studio 16.4 Preview 2 in the Tools Options menu.</p>\n<img width=\"833\" alt=\"New semicolon formatter option in VS Code\" src=\"https://user-images.githubusercontent.com/3277153/65913194-10066e80-e395-11e9-8a3a-4f7305c397d5.png\">\n<p>Choosing a value of “insert” or “remove” 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 “ignore” makes generated code match the semicolon preference detected in the current file.</p>\n<h2 id=\"37-breaking-changes\" style=\"position:relative;\"><a href=\"#37-breaking-changes\" aria-label=\"37 breaking changes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3.7 Breaking Changes</h2>\n<h3 id=\"dom-changes\" style=\"position:relative;\"><a href=\"#dom-changes\" aria-label=\"dom changes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>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>.\nThese changes are largely correctness changes related to nullability, but impact will ultimately depend on your codebase.</p>\n<h3 id=\"class-field-mitigations\" style=\"position:relative;\"><a href=\"#class-field-mitigations\" aria-label=\"class field mitigations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Class Field Mitigations</h3>\n<p><a href=\"#the-usedefineforclassfields-flag-and-the-declare-property-modifier\">As mentioned above</a>, TypeScript 3.7 emits <code>get</code>/<code>set</code> accessors in <code>.d.ts</code> files which can cause breaking changes for consumers on older versions of TypeScript like 3.5 and prior.\nTypeScript 3.6 users will not be impacted, since that version was future-proofed for this feature.</p>\n<p>While not a breakage per se, opting in to the <code>useDefineForClassFields</code> flag can cause breakage when:</p>\n<ul>\n<li>overriding an accessor in a derived class with a property declaration</li>\n<li>re-declaring a property declaration with no initializer</li>\n</ul>\n<p>To understand the full impact, read <a href=\"#the-usedefineforclassfields-flag-and-the-declare-property-modifier\">the section above on the <code>useDefineForClassFields</code> flag</a>.</p>\n<h3 id=\"function-truthy-checks\" style=\"position:relative;\"><a href=\"#function-truthy-checks\" aria-label=\"function truthy checks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Function Truthy Checks</h3>\n<p>As mentioned above, TypeScript now errors when functions appear to be uncalled within <code>if</code> statement conditions.\nAn 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\" style=\"position:relative;\"><a href=\"#local-and-imported-type-declarations-now-conflict\" aria-label=\"local and imported type declarations now conflict permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Local and Imported Type Declarations Now Conflict</h3>\n<p>Due to a bug, the following construct was previously allowed in TypeScript:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// ./someOtherModule.ts</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> SomeType {</span>\n<span style=\"color: #000000\">  y: string;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// ./myModule.ts</span>\n<span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> { SomeType } </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"./someOtherModule\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> SomeType {</span>\n<span style=\"color: #000000\">  x: number;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> fn(arg: SomeType) {</span>\n<span style=\"color: #000000\">  console.log(arg.x); </span><span style=\"color: #008000\">// Error! 'x' doesn't exist on 'SomeType'</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Here, <code>SomeType</code> appears to originate in both the <code>import</code> declaration and the local <code>interface</code> declaration.\nPerhaps 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.\nThis 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>.\nThe correct fix depends on the original intent of the author and should be addressed on a case-by-case basis.\nUsually, the naming conflict is unintentional and the best fix is to rename the imported type.\nIf the intent was to augment the imported type, a proper module augmentation should be written instead.</p>\n<h3 id=\"37-api-changes\" style=\"position:relative;\"><a href=\"#37-api-changes\" aria-label=\"37 api changes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3.7 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>","headings":[{"value":"Optional Chaining","depth":2},{"value":"Nullish Coalescing","depth":2},{"value":"Assertion Functions","depth":2},{"value":"Better Support for never-Returning Functions","depth":2},{"value":"(More) Recursive Type Aliases","depth":2},{"value":"--declaration and --allowJs","depth":2},{"value":"The useDefineForClassFields Flag and The declare Property Modifier","depth":2},{"value":"Build-Free Editing with Project References","depth":2},{"value":"Uncalled Function Checks","depth":2},{"value":"// @ts-nocheck in TypeScript Files","depth":2},{"value":"Semicolon Formatter Option","depth":2},{"value":"3.7 Breaking Changes","depth":2},{"value":"DOM Changes","depth":3},{"value":"Class Field Mitigations","depth":3},{"value":"Function Truthy Checks","depth":3},{"value":"Local and Imported Type Declarations Now Conflict","depth":3},{"value":"3.7 API Changes","depth":3}],"frontmatter":{"permalink":"/docs/handbook/release-notes/typescript-3-7.html","title":"TypeScript 3.7"}}},"pageContext":{"slug":"/docs/handbook/release-notes/typescript-3-7.html","isOldHandbook":true}}}