{"id":3438,"date":"2022-05-11T14:07:06","date_gmt":"2022-05-11T22:07:06","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=3438"},"modified":"2022-05-11T14:42:32","modified_gmt":"2022-05-11T22:42:32","slug":"announcing-typescript-4-7-rc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-7-rc\/","title":{"rendered":"Announcing TypeScript 4.7 RC"},"content":{"rendered":"<p>Today we&#8217;re excited to announce our Release Candidate (RC) of TypeScript 4.7!\nBetween now and the stable release of TypeScript 4.7, we expect no further changes apart from critical bug fixes.<\/p>\n<p>To get started using the RC, you can get it <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild\">through NuGet<\/a>, or use npm with the following command:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000000;\">npm install typescript@rc<\/span>\r\n<\/code><\/pre>\n<p>You can also get editor support by<\/p>\n<ul>\n<li><a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=TypeScriptTeam.TypeScript-47rc\">Downloading for Visual Studio 2022\/2019<\/a><\/li>\n<li>Following directions for <a href=\"https:\/\/code.visualstudio.com\/Docs\/languages\/typescript#_using-newer-typescript-versions\">Visual Studio Code<\/a> and <a href=\"https:\/\/github.com\/Microsoft\/TypeScript-Sublime-Plugin\/#note-using-different-versions-of-typescript\">Sublime Text 3<\/a>.<\/li>\n<\/ul>\n<p>Here&#8217;s a quick list of what&#8217;s new in TypeScript 4.7!<\/p>\n<ul>\n<li><a href=\"#esm-nodejs\">ECMAScript Module Support in Node.js<\/a><\/li>\n<li><a href=\"#control-over-module-detection\">Control over Module Detection<\/a><\/li>\n<li><a href=\"#control-flow-analysis-for-computed-properties\">Control-Flow Analysis for Computed Properties<\/a><\/li>\n<li><a href=\"#improved-function-inference-in-objects-and-methods\">Improved Function Inference in Objects and Methods<\/a><\/li>\n<li><a href=\"#instantiation-expressions\">Instantiation Expressions<\/a><\/li>\n<li><a href=\"#extends-constraints-on-infer-type-variables\"><code>extends<\/code> Constraints on <code>infer<\/code> Type Variables<\/a><\/li>\n<li><a href=\"#optional-variance-annotations-for-type-parameters\">Optional Variance Annotations for Type Parameters<\/a><\/li>\n<li><a href=\"#resolution-customization-with-modulesuffixes\">Resolution Customization with <code>moduleSuffixes<\/code><\/a><\/li>\n<li><a href=\"#resolution-mode\"><code>resolution-mode<\/code><\/a><\/li>\n<li><a href=\"#go-to-source-definition\">Go to Source Definition<\/a><\/li>\n<li><a href=\"#group-aware-organize-imports\">Groups-Aware Organize Imports<\/a><\/li>\n<li><a href=\"#object-method-snippet-completions\">Object Method Snippet Completions<\/a><\/li>\n<li><a href=\"#breaking-changes\">Breaking Changes<\/a><\/li>\n<\/ul>\n<h2><a name=\"beta-delta\"><\/a> What&#8217;s New Since the Beta?<\/h2>\n<p>In our beta release, we announced a stable target for our Node ESM support called <code>node12<\/code>; however, Node.js 12 is no longer under maintenance, so we&#8217;ve started the stable target at <code>node16<\/code>.\nThis should provide newer ES module functionality from Node.js (like <a href=\"https:\/\/github.com\/nodejs\/node\/pull\/39635\">pattern trailers<\/a>) while also defaulting TypeScript to a higher <code>target<\/code> that supports top-level <code>await<\/code>.<\/p>\n<p>Since the beta, the <a href=\"#resolution-mode\"><code>resolution-mode<\/code><\/a> syntax is still available for <code>\/\/\/ &lt;reference types=&quot;...&quot; \/&gt;<\/code> directives;\nhowever, we received some feedback on <code>import type<\/code> and wanted to reconsider the needs and design of the feature.\nIn turn, <code>resolution-mode<\/code> is only available experimentally in <code>import type<\/code> in nightly versions of TypeScript.<\/p>\n<p>After the beta, we realized that <code>typeof<\/code> on <code>#private<\/code> fields has issues with API compatibility.\nWe also found ourselves asking whether <code>typeof this.#somePrivate<\/code> composes well on something more important: declaration emit.\nAs a result, the feature will not be in TypeScript 4.7.<\/p>\n<p>This release also includes a new preview editor command for <a href=\"#go-to-source-definition\"><em>Go to Source Definition<\/em><\/a>.\nThis can be helpful in cases where an ordinary <em>Go to Definition<\/em> comand would take you to a declaration file instead of the actual JavaScript or TypeScript source.\n<a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/49003\">We&#8217;re still looking for feedback on this feature<\/a>!<\/p>\n<p>Some <a href=\"#breaking-changes\">breaking changes<\/a> since the beta, including rules around stricter type parameter constraints in <code>strictNullChecks<\/code> and arrow function parsing have been backed out.\nUnfortunately, some innocuous-looking changes have introduced stricter rules around JSX <code>...spread<\/code>s and generics used in template strings, which are new breaks since the beta.<\/p>\n<h2><a name=\"esm-nodejs\"><\/a> ECMAScript Module Support in Node.js<\/h2>\n<p>For the last few years, Node.js has been working to support ECMAScript modules (ESM).\nThis has been a very difficult feature, since the Node.js ecosystem is built on a different module system called CommonJS (CJS).\nInteroperating between the two brings large challenges, with many new features to juggle;\nhowever, support for ESM in Node.js was largely implemented in Node.js 12 and later.\nAround TypeScript 4.5 we rolled out nightly-only support for ESM in Node.js to get some feedback from users and let library authors ready themselves for broader support.<\/p>\n<p>TypeScript 4.7 adds this functionality with two new <code>module<\/code> settings: <code>node16<\/code> and <code>nodenext<\/code>.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000000;\">{<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;compilerOptions&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #0451A5;\">&quot;module&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;node16&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    }<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>These new modes bring a few high-level features which we&#8217;ll explore here.<\/p>\n<h3><code>type<\/code> in <code>package.json<\/code> and New Extensions<\/h3>\n<p>Node.js supports <a href=\"https:\/\/nodejs.org\/api\/packages.html#packages_package_json_and_file_extensions\">a new setting in <code>package.json<\/code><\/a> called <code>type<\/code>.\n<code>&quot;type&quot;<\/code> can be set to either <code>&quot;module&quot;<\/code> or <code>&quot;commonjs&quot;<\/code>.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000000;\">{<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;name&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;my-package&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;type&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;module&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;\/\/&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;...&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;dependencies&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">    }<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>This setting controls whether <code>.js<\/code> files are interpreted as ES modules or CommonJS modules, and defaults to CommonJS when not set.\nWhen a file is considered an ES module, a few different rules come into play compared to CommonJS:<\/p>\n<ul>\n<li><code>import<\/code>\/<code>export<\/code> statements can be used.<\/li>\n<li>top-level <code>await<\/code> can be used<\/li>\n<li>Relative import paths need full extensions (we have to write <code>import &quot;.\/foo.js&quot;<\/code> instead of <code>import &quot;.\/foo&quot;<\/code>).<\/li>\n<li>Imports might resolve differently from dependencies in <code>node_modules<\/code>.<\/li>\n<li>Certain global-like values like <code>require()<\/code> and <code>process<\/code> cannot be used directly.<\/li>\n<li>CommonJS modules get imported under certain special rules.<\/li>\n<\/ul>\n<p>We&#8217;ll come back to some of these.<\/p>\n<p>To overlay the way TypeScript works in this system, <code>.ts<\/code> and <code>.tsx<\/code> files now work the same way.\nWhen TypeScript finds a <code>.ts<\/code>, <code>.tsx<\/code>, <code>.js<\/code>, or <code>.jsx<\/code> file, it will walk up looking for a <code>package.json<\/code> to see whether that file is an ES module, and use that to determine:<\/p>\n<ul>\n<li>how to find other modules which that file imports<\/li>\n<li>and how to transform that file if producing outputs<\/li>\n<\/ul>\n<p>When a <code>.ts<\/code> file is compiled as an ES module, ECMAScript <code>import<\/code>\/<code>export<\/code> statements are left alone in the <code>.js<\/code> output;\nwhen it&#8217;s compiled as a CommonJS module, it will produce the same output you get today under <code>--module commonjs<\/code>.<\/p>\n<p>This also means paths resolve differently between <code>.ts<\/code> files that are ES modules and ones that are CJS modules.\nFor example, let&#8217;s say you have the following code today:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ .\/foo.ts<\/span>\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">() {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ ...<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ .\/bar.ts<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #001080;\">helper<\/span><span style=\"color: #000000;\"> } <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/foo&quot;<\/span><span style=\"color: #000000;\">; <\/span><span style=\"color: #008000;\">\/\/ only works in CJS<\/span>\r\n\r\n<span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">();<\/span>\r\n<\/code><\/pre>\n<p>This code works in CommonJS modules, but will fail in ES modules because relative import paths need to use extensions.\nAs a result, it will have to be rewritten to use the extension of the <em>output<\/em> of <code>foo.ts<\/code> &#8211; so <code>bar.ts<\/code> will instead have to import from <code>.\/foo.js<\/code>.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ .\/bar.ts<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #001080;\">helper<\/span><span style=\"color: #000000;\"> } <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/foo.js&quot;<\/span><span style=\"color: #000000;\">; <\/span><span style=\"color: #008000;\">\/\/ works in ESM &amp; CJS<\/span>\r\n\r\n<span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">();<\/span>\r\n<\/code><\/pre>\n<p>This might feel a bit cumbersome at first, but TypeScript tooling like auto-imports and path completion will typically just do this for you.<\/p>\n<p>One other thing to mention is the fact that this applies to <code>.d.ts<\/code> files too.\nWhen TypeScript finds a <code>.d.ts<\/code> file in package, it is interpreted based on the containing package.<\/p>\n<h3>New File Extensions<\/h3>\n<p>The <code>type<\/code> field in <code>package.json<\/code> is nice because it allows us to continue using the <code>.ts<\/code> and <code>.js<\/code> file extensions which can be convenient;\nhowever, you will occasionally need to write a file that differs from what <code>type<\/code> specifies.\nYou might also just prefer to always be explicit.<\/p>\n<p>Node.js supports two extensions to help with this: <code>.mjs<\/code> and <code>.cjs<\/code>.\n<code>.mjs<\/code> files are always ES modules, and <code>.cjs<\/code> files are always CommonJS modules, and there&#8217;s no way to override these.<\/p>\n<p>In turn, TypeScript supports two new source file extensions: <code>.mts<\/code> and <code>.cts<\/code>.\nWhen TypeScript emits these to JavaScript files, it will emit them to <code>.mjs<\/code> and <code>.cjs<\/code> respectively.<\/p>\n<p>Furthermore, TypeScript also supports two new declaration file extensions: <code>.d.mts<\/code> and <code>.d.cts<\/code>.\nWhen TypeScript generates declaration files for <code>.mts<\/code> and <code>.cts<\/code>, their corresponding extensions will be <code>.d.mts<\/code> and <code>.d.cts<\/code>.<\/p>\n<p>Using these extensions is entirely optional, but will often be useful even if you choose not to use them as part of your primary workflow.<\/p>\n<h3>CommonJS Interop<\/h3>\n<p>Node.js allows ES modules to import CommonJS modules as if they were ES modules with a default export.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ .\/foo.cts<\/span>\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">() {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;hello world!&quot;<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ .\/bar.mts<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">foo<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/foo.cjs&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ prints &quot;hello world!&quot;<\/span>\r\n<span style=\"color: #001080;\">foo<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">();<\/span>\r\n<\/code><\/pre>\n<p>In some cases, Node.js also synthesizes named exports from CommonJS modules, which can be more convenient.\nIn these cases, ES modules can use a &quot;namespace-style&quot; import (i.e. <code>import * as foo from &quot;...&quot;<\/code>), or named imports (i.e. <code>import { helper } from &quot;...&quot;<\/code>).<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ .\/foo.cts<\/span>\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">() {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;hello world!&quot;<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ .\/bar.mts<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #001080;\">helper<\/span><span style=\"color: #000000;\"> } <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/foo.cjs&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ prints &quot;hello world!&quot;<\/span>\r\n<span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">();<\/span>\r\n<\/code><\/pre>\n<p>There isn&#8217;t always a way for TypeScript to know whether these named imports will be synthesized, but TypeScript will err on being permissive and use some heuristics when importing from a file that is definitely a CommonJS module.<\/p>\n<p>One TypeScript-specific note about interop is the following syntax:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">foo<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #AF00DB;\">require<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;foo&quot;<\/span><span style=\"color: #000000;\">);<\/span>\r\n<\/code><\/pre>\n<p>In a CommonJS module, this just boils down to a <code>require()<\/code> call, and in an ES module, this imports <a href=\"https:\/\/nodejs.org\/api\/module.html#module_module_createrequire_filename\"><code>createRequire<\/code><\/a> to achieve the same thing.\nThis will make code less portable on runtimes like the browser (which don&#8217;t support <code>require()<\/code>), but will often be useful for interoperability.\nIn turn, you can write the above example using this syntax as follows:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ .\/foo.cts<\/span>\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">() {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;hello world!&quot;<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ .\/bar.mts<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">foo<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #AF00DB;\">require<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;.\/foo.cjs&quot;<\/span><span style=\"color: #000000;\">);<\/span>\r\n\r\n<span style=\"color: #001080;\">foo<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">helper<\/span><span style=\"color: #000000;\">()<\/span>\r\n<\/code><\/pre>\n<p>Finally, it&#8217;s worth noting that the only way to import ESM files from a CJS module is using dynamic <code>import()<\/code> calls.\nThis can present challenges, but is the behavior in Node.js today.<\/p>\n<p>You can <a href=\"https:\/\/nodejs.org\/api\/esm.html#esm_interoperability_with_commonjs\">read more about ESM\/CommonJS interop in Node.js here<\/a>.<\/p>\n<h3><code>package.json<\/code> Exports, Imports, and Self-Referencing<\/h3>\n<p>Node.js supports <a href=\"https:\/\/nodejs.org\/api\/packages.html#packages_exports\">a new field for defining entry points in <code>package.json<\/code> called <code>&quot;exports&quot;<\/code><\/a>.\nThis field is a more powerful alternative to defining <code>&quot;main&quot;<\/code> in <code>package.json<\/code>, and can control what parts of your package are exposed to consumers.<\/p>\n<p>Here&#8217;s an <code>package.json<\/code> that supports separate entry-points for CommonJS and ESM:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ package.json<\/span>\r\n<span style=\"color: #000000;\">{<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;name&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;my-package&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;type&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;module&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;exports&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #0451A5;\">&quot;.&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #008000;\">\/\/ Entry-point for `import &quot;my-package&quot;` in ESM<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #0451A5;\">&quot;import&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/esm\/index.js&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #008000;\">\/\/ Entry-point for `require(&quot;my-package&quot;) in CJS<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #0451A5;\">&quot;require&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/commonjs\/index.cjs&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">        },<\/span>\r\n<span style=\"color: #000000;\">    },<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ CJS fall-back for older versions of Node.js<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;main&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/commonjs\/index.cjs&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>There&#8217;s a lot to this feature, <a href=\"https:\/\/nodejs.org\/api\/packages.html\">which you can read more about on the Node.js documentation<\/a>.\nHere we&#8217;ll try to focus on how TypeScript supports it.<\/p>\n<p>With TypeScript&#8217;s original Node support, it would look for a <code>&quot;main&quot;<\/code> field, and then look for declaration files that corresponded to that entry.\nFor example, if <code>&quot;main&quot;<\/code> pointed to <code>.\/lib\/index.js<\/code>, TypeScript would look for a file called <code>.\/lib\/index.d.ts<\/code>.\nA package author could override this by specifying a separate field called <code>&quot;types&quot;<\/code> (e.g. <code>&quot;types&quot;: &quot;.\/types\/index.d.ts&quot;<\/code>).<\/p>\n<p>The new support works similarly with <a href=\"https:\/\/nodejs.org\/api\/packages.html\">import conditions<\/a>.\nBy default, TypeScript overlays the same rules with import conditions &#8211; if you write an <code>import<\/code> from an ES module, it will look up the <code>import<\/code> field, and from a CommonJS module, it will look at the <code>require<\/code> field.\nIf it finds them, it will look for a corresponding declaration file.\nIf you need to point to a different location for your type declarations, you can add a <code>&quot;types&quot;<\/code> import condition.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ package.json<\/span>\r\n<span style=\"color: #000000;\">{<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;name&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;my-package&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;type&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;module&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;exports&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #0451A5;\">&quot;.&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #008000;\">\/\/ Entry-point for `import &quot;my-package&quot;` in ESM<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #0451A5;\">&quot;import&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #008000;\">\/\/ Where TypeScript will look.<\/span>\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #0451A5;\">&quot;types&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/types\/esm\/index.d.ts&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #008000;\">\/\/ Where Node.js will look.<\/span>\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #0451A5;\">&quot;default&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/esm\/index.js&quot;<\/span>\r\n<span style=\"color: #000000;\">            },<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #008000;\">\/\/ Entry-point for `require(&quot;my-package&quot;) in CJS<\/span>\r\n<span style=\"color: #000000;\">            <\/span><span style=\"color: #0451A5;\">&quot;require&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #008000;\">\/\/ Where TypeScript will look.<\/span>\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #0451A5;\">&quot;types&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/types\/commonjs\/index.d.cts&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #008000;\">\/\/ Where Node.js will look.<\/span>\r\n<span style=\"color: #000000;\">                <\/span><span style=\"color: #0451A5;\">&quot;default&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/commonjs\/index.cjs&quot;<\/span>\r\n<span style=\"color: #000000;\">            },<\/span>\r\n<span style=\"color: #000000;\">        }<\/span>\r\n<span style=\"color: #000000;\">    },<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Fall-back for older versions of TypeScript<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;types&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/types\/index.d.ts&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ CJS fall-back for older versions of Node.js<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;main&quot;<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #A31515;\">&quot;.\/commonjs\/index.cjs&quot;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<aside>\n<p>Note that the <code>&quot;types&quot;<\/code> condition should always come first in <code>&quot;exports&quot;<\/code>.<\/p>\n<\/aside>\n<p>TypeScript also supports <a href=\"https:\/\/nodejs.org\/api\/packages.html#packages_imports\">the <code>&quot;imports&quot;<\/code> field of <code>package.json<\/code><\/a> in a similar manner (looking for declaration files alongside corresponding files), and supports <a href=\"https:\/\/nodejs.org\/api\/packages.html#packages_self_referencing_a_package_using_its_name\">packages self-referencing themselves<\/a>.\nThese features are generally not as involved, but are supported.<\/p>\n<h3>Your Feedback Wanted!<\/h3>\n<p>As we continue working on TypeScript 4.7, we expect to see more documentation and polish go into this functionality.\nSupporting these new features has been an ambitious under-taking, and that&#8217;s why we&#8217;re looking for early feedback on it!\nPlease try it out and let us know how it works for you.<\/p>\n<p>For more information, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/44501\">you can see the implementing PR here<\/a>.<\/p>\n<h2><a name=\"control-over-module-detection\"><\/a> Control over Module Detection<\/h2>\n<p>One issue with the introduction of modules to JavaScript was the ambiguity between existing &quot;script&quot; code and the new module code.\nJavaScript code in a module runs slightly differently, and has different scoping rules, so tools have to make decisions as to how each file runs.\nFor example, Node.js requires module entry-points to be written in a <code>.mjs<\/code>, or have a nearby <code>package.json<\/code> with <code>&quot;type&quot;: &quot;module&quot;<\/code>.\nTypeScript treats a file as a module whenever it finds any <code>import<\/code> or <code>export<\/code> statement in a file, but otherwise, will assume a <code>.ts<\/code> or <code>.js<\/code> file is a script file acting on the global scope.<\/p>\n<p>This doesn&#8217;t quite match up with the behavior of Node.js where the <code>package.json<\/code> can change the format of a file, or the <code>--jsx<\/code> setting <code>react-jsx<\/code>, where any JSX file contains an implicit import to a JSX factory.\nIt also doesn&#8217;t match modern expectations where most new TypeScript code is written with modules in mind.<\/p>\n<p>That&#8217;s why TypeScript 4.7 introduces a new option called <code>moduleDetection<\/code>.\n<code>moduleDetection<\/code> can take on 3 values: <code>&quot;auto&quot;<\/code> (the default), <code>&quot;legacy&quot;<\/code> (the same behavior as 4.6 and prior), and <code>&quot;force&quot;<\/code>.<\/p>\n<p>Under the mode <code>&quot;auto&quot;<\/code>, TypeScript will not only look for <code>import<\/code> and <code>export<\/code> statements, but it will also check whether<\/p>\n<ul>\n<li>the <code>&quot;type&quot;<\/code> field in <code>package.json<\/code> is set to <code>&quot;module&quot;<\/code> when running under <code>--module nodenext<\/code>\/<code>--module node16<\/code>, and<\/li>\n<li>check whether the current file is a JSX file when running under <code>--jsx react-jsx<\/code><\/li>\n<\/ul>\n<p>In cases where you want every file to be treated as a module, the <code>&quot;force&quot;<\/code> setting ensures that every non-declaration file is treated as a module.\nThis will be true regardless of how <code>module<\/code>, <code>moduleResoluton<\/code>, and <code>jsx<\/code> are configured.<\/p>\n<p>Meanwhile, the <code>&quot;legacy&quot;<\/code> option simply goes back to the old behavior of only seeking out <code>import<\/code> and <code>export<\/code> statements to determine whether a file is a module.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47495\">read up more about this change on the pull request<\/a>.<\/p>\n<h2><a name=\"control-flow-analysis-for-computed-properties\"><\/a> Control-Flow Analysis for Computed Properties<\/h2>\n<p>TypeScript 4.7 now analyzes the type of computed properties whose keys are literal types and unique symbols, and narrows them correctly.\nFor example, take the following code:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">key<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">Symbol<\/span><span style=\"color: #000000;\">();<\/span>\r\n\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">numberOrString<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">Math<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">random<\/span><span style=\"color: #000000;\">() &lt; <\/span><span style=\"color: #098658;\">0.5<\/span><span style=\"color: #000000;\"> ? <\/span><span style=\"color: #098658;\">42<\/span><span style=\"color: #000000;\"> : <\/span><span style=\"color: #A31515;\">&quot;hello&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">obj<\/span><span style=\"color: #000000;\"> = {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">[key]:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">numberOrString<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">};<\/span>\r\n\r\n<span style=\"color: #AF00DB;\">if<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #0000FF;\">typeof<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">obj<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">] === <\/span><span style=\"color: #A31515;\">&quot;string&quot;<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">let<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">str<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">obj<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">].<\/span><span style=\"color: #795E26;\">toUpperCase<\/span><span style=\"color: #000000;\">();<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>Previously, TypeScript would not consider any type guards on <code>obj[key]<\/code>, and would have no idea that <code>obj[key]<\/code> was really a <code>string<\/code>.\nInstead, it would think that <code>obj[key]<\/code> was still a <code>string | number<\/code> and accessing <code>toUpperCase()<\/code> would trigger an error.<\/p>\n<p>TypeScript 4.7 now knows that <code>obj[key]<\/code> is a string.<\/p>\n<p>This also means that under <code>--strictPropertyInitialization<\/code>, TypeScript can correctly check that computed properties are initialized by the end of a constructor body.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ 'key' has type 'unique symbol'<\/span>\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">key<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">Symbol<\/span><span style=\"color: #000000;\">();<\/span>\r\n\r\n<span style=\"color: #0000FF;\">class<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">C<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    [<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">]: <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">constructor<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">str<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #008000;\">\/\/ oops, forgot to set 'this[key]'<\/span>\r\n<span style=\"color: #000000;\">    }<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">screamString<\/span><span style=\"color: #000000;\">() {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">this<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">].<\/span><span style=\"color: #795E26;\">toUpperCase<\/span><span style=\"color: #000000;\">();<\/span>\r\n<span style=\"color: #000000;\">    }<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>Under TypeScript 4.7, <code>--strictPropertyInitialization<\/code> reports an error telling us that the <code>[key]<\/code> property wasn&#8217;t definitely assigned by the end of the constructor.<\/p>\n<p>We&#8217;d like to extend our gratitude to <a href=\"https:\/\/github.com\/a-tarasyuk\">Oleksandr Tarasiuk<\/a> who provided <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/45974\">this change<\/a>!<\/p>\n<h2><a name=\"improved-function-inference-in-objects-and-methods\"><\/a> Improved Function Inference in Objects and Methods<\/h2>\n<p>TypeScript 4.7 can now perform more granular inferences from functions within objects and arrays.\nThis allows the types of these functions to consistently flow in a left-to-right manner just like for plain arguments.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">declare<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">f<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;(<\/span><span style=\"color: #001080;\">arg<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">produce<\/span><span style=\"color: #000000;\">: (<\/span><span style=\"color: #001080;\">n<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">consume<\/span><span style=\"color: #000000;\">: (<\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\"> }<\/span>\r\n<span style=\"color: #000000;\">): <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Works<\/span>\r\n<span style=\"color: #795E26;\">f<\/span><span style=\"color: #000000;\">({<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">produce<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> () <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;hello&quot;<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">consume<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">toLowerCase<\/span><span style=\"color: #000000;\">()<\/span>\r\n<span style=\"color: #000000;\">});<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Works<\/span>\r\n<span style=\"color: #795E26;\">f<\/span><span style=\"color: #000000;\">({<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">produce<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #001080;\">n<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">n<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">consume<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">toLowerCase<\/span><span style=\"color: #000000;\">(),<\/span>\r\n<span style=\"color: #000000;\">});<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Was an error, now works.<\/span>\r\n<span style=\"color: #795E26;\">f<\/span><span style=\"color: #000000;\">({<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">produce<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">n<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">n<\/span><span style=\"color: #000000;\">,<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">consume<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">toLowerCase<\/span><span style=\"color: #000000;\">(),<\/span>\r\n<span style=\"color: #000000;\">});<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Was an error, now works.<\/span>\r\n<span style=\"color: #795E26;\">f<\/span><span style=\"color: #000000;\">({<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">produce<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> () { <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;hello&quot;<\/span><span style=\"color: #000000;\">; },<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">consume<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">toLowerCase<\/span><span style=\"color: #000000;\">(),<\/span>\r\n<span style=\"color: #000000;\">});<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Was an error, now works.<\/span>\r\n<span style=\"color: #795E26;\">f<\/span><span style=\"color: #000000;\">({<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">produce<\/span><span style=\"color: #000000;\">() { <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;hello&quot;<\/span><span style=\"color: #000000;\"> },<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">consume<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">toLowerCase<\/span><span style=\"color: #000000;\">(),<\/span>\r\n<span style=\"color: #000000;\">});<\/span>\r\n<\/code><\/pre>\n<p>Inference failed in some of these examples because knowing the type of their <code>produce<\/code> functions would indirectly request the the of <code>arg<\/code> before finding a good type for <code>T<\/code>.\nTypeScript now gathers functions that could contribute to the inferred type of <code>T<\/code> and infers from them lazily.<\/p>\n<p>For more information, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48538\">take a look at the specific modifications to our inference process<\/a>.<\/p>\n<h2><a name=\"instantiation-expressions\"><\/a> Instantiation Expressions<\/h2>\n<p>Occasionally functions can be a bit more general than we want.\nFor example, let&#8217;s say we had a <code>makeBox<\/code> function.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Box<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">makeBox<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;(<\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\"> };<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>Maybe we want to create a more specialized set of functions for making <code>Box<\/code>es of <code>Wrench<\/code>es and <code>Hammer<\/code>s.\nTo do that today, we&#8217;d have to wrap <code>makeBox<\/code> in other functions, or use an explicit type for an alias of <code>makeBox<\/code>.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">makeHammerBox<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">hammer<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Hammer<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">makeBox<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">hammer<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ or...<\/span>\r\n\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">makeWrenchBox<\/span><span style=\"color: #000000;\">: (<\/span><span style=\"color: #001080;\">wrench<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Wrench<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Box<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">Wrench<\/span><span style=\"color: #000000;\">&gt; = <\/span><span style=\"color: #001080;\">makeBox<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p>These work, but wrapping a call to <code>makeBox<\/code> is a bit wasteful, and writing the full signature of <code>makeWrenchBox<\/code> could get unwieldy.\nIdeally, we would be able to say that we just want to alias <code>makeBox<\/code> while replacing all of the generics in its signature.<\/p>\n<p>TypeScript 4.7 allows exactly that!\nWe can now take functions and constructors and feed them type arguments directly.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">makeHammerBox<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">makeBox<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #001080;\">Hammer<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">makeWrenchBox<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">makeBox<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #001080;\">Wrench<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n<\/code><\/pre>\n<p>So with this, we can specialize <code>makeBox<\/code> to accept more specific types and reject anything else.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">makeStringBox<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">makeBox<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #001080;\">string<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ TypeScript correctly rejects this.<\/span>\r\n<span style=\"color: #795E26;\">makeStringBox<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #098658;\">42<\/span><span style=\"color: #000000;\">);<\/span>\r\n<\/code><\/pre>\n<p>This logic also works for constructor functions such as <code>Array<\/code>, <code>Map<\/code>, and <code>Set<\/code>.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ Has type `new () =&gt; Map&lt;string, Error&gt;`<\/span>\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">ErrorMap<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">Map<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #001080;\">string<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #0070C1;\">Error<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Has type `\/\/ Map&lt;string, Error&gt;`<\/span>\r\n<span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">errorMap<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #0000FF;\">new<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">ErrorMap<\/span><span style=\"color: #000000;\">();<\/span>\r\n<\/code><\/pre>\n<p>When a function or constructor is given type arguments, it will produce a new type that keeps all signatures with compatible type parameter lists, and replaces the corresponding type parameters with the given type arguments.\nAny other signatures are dropped, as TypeScript will assume that they aren&#8217;t meant to be used.<\/p>\n<p>For more information on this feature, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47607\">check out the pull request<\/a>.<\/p>\n<h2><a name=\"extends-constraints-on-infer-type-variables\"><\/a> <code>extends<\/code> Constraints on <code>infer<\/code> Type Variables<\/h2>\n<p>Conditional types are a bit of a power-user feature.\nThey allow us to match and infer against the shape of types, and make decisions based on them.\nFor example, we can write a conditional type that returns the first element of a tuple type if it&#8217;s a <code>string<\/code>-like type.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; =<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #0000FF;\">infer<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\">, ...<\/span><span style=\"color: #267F99;\">unknown<\/span><span style=\"color: #000000;\">[]]<\/span>\r\n<span style=\"color: #000000;\">        ? <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\"> ? <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> : <\/span><span style=\"color: #267F99;\">never<\/span>\r\n<span style=\"color: #000000;\">        : <\/span><span style=\"color: #267F99;\">never<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #000000;\"> <\/span><span style=\"color: #008000;\">\/\/ string<\/span>\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">A<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;[<\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">number<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">number<\/span><span style=\"color: #000000;\">]&gt;;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ &quot;hello&quot;<\/span>\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">B<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;[<\/span><span style=\"color: #A31515;\">&quot;hello&quot;<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">number<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">number<\/span><span style=\"color: #000000;\">]&gt;;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ &quot;hello&quot; | &quot;world&quot;<\/span>\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">C<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;[<\/span><span style=\"color: #A31515;\">&quot;hello&quot;<\/span><span style=\"color: #000000;\"> | <\/span><span style=\"color: #A31515;\">&quot;world&quot;<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">boolean<\/span><span style=\"color: #000000;\">]&gt;;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ never<\/span>\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">D<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;[<\/span><span style=\"color: #267F99;\">boolean<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">number<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">]&gt;;<\/span>\r\n<\/code><\/pre>\n<p><code>FirstIfString<\/code> matches against any tuple with at least one element and grabs the type of the first element as <code>S<\/code>.\nThen it checks if <code>S<\/code> is compatible with <code>string<\/code> and returns that type if it is.<\/p>\n<p>Note that we had to use two conditional types to write this.\nWe could have written <code>FirstIfString<\/code> as follows:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; =<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">, ...<\/span><span style=\"color: #267F99;\">unknown<\/span><span style=\"color: #000000;\">[]]<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #008000;\">\/\/ Grab the first type out of `T`<\/span>\r\n<span style=\"color: #000000;\">        ? <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #098658;\">0<\/span><span style=\"color: #000000;\">]<\/span>\r\n<span style=\"color: #000000;\">        : <\/span><span style=\"color: #267F99;\">never<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p>This works, but it&#8217;s slightly more &quot;manual&quot; and less declarative.\nInstead of just pattern-matching on the type and giving the first element a name, we have to fetch out the <code>0<\/code>th element of <code>T<\/code> with <code>T[0]<\/code>.\nIf we were dealing with types more complex than tuples, this could get a lot trickier, so conditionals can simplify things.<\/p>\n<p>Using nested conditionals to infer a type and then match against that inferred type is pretty common.\nTo avoid that second level of nesting, TypeScript 4.7 now allows you to place a constraint on any <code>infer<\/code> type.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">FirstIfString<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; =<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #0000FF;\">infer<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">, ...<\/span><span style=\"color: #267F99;\">unknown<\/span><span style=\"color: #000000;\">[]]<\/span>\r\n<span style=\"color: #000000;\">        ? <\/span><span style=\"color: #267F99;\">S<\/span>\r\n<span style=\"color: #000000;\">        : <\/span><span style=\"color: #267F99;\">never<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p>This way, when TypeScript matches against <code>S<\/code>, it also ensures that <code>S<\/code> has to be a <code>string<\/code>.\nIf <code>S<\/code> isn&#8217;t a <code>string<\/code>, it takes the false path, which in this cases is <code>never<\/code>.<\/p>\n<p>For more details, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48112\">read up on the change on GitHub<\/a>.<\/p>\n<h2><a name=\"optional-variance-annotations-for-type-parameters\"><\/a> Optional Variance Annotations for Type Parameters<\/h2>\n<p>Let&#8217;s take the following types.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Animal<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">animalStuff<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">any<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Dog<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Animal<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">dogStuff<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">any<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ ...<\/span>\r\n\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Getter<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; = () <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Setter<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; = (<\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p>Imagine we had two different instances of <code>Getter<\/code>s.\nFiguring out whether any two different <code>Getter<\/code>s are substitutable for one another depends entirely on <code>T<\/code>.\nIn the case of whether an assignment of <code>Getter&lt;Dog&gt;<\/code>\u00a0\u2192\u00a0<code>Getter&lt;Animal&gt;<\/code> is valid, we have to check whether <code>Dog<\/code>\u00a0\u2192\u00a0<code>Animal<\/code> is valid.\nBecause each type for <code>T<\/code> just gets related in the same &quot;direction&quot;, we say that the <code>Getter<\/code> type is <em>covariant<\/em> on <code>T<\/code>.\nOn the other hand, checking whether <code>Setter&lt;Dog&gt;<\/code>\u00a0\u2192\u00a0<code>Setter&lt;Animal&gt;<\/code> is valid involves checking whether <code>Animal<\/code>\u00a0\u2192\u00a0<code>Dog<\/code> is valid.\nThat &quot;flip&quot; in direction is kind of like how in math, checking whether \u2212<em>x<\/em>\u00a0&lt;\u00a0<em>\u2212y<\/em> is the same as checking whether <em>y<\/em>\u00a0&lt;\u00a0<em>x<\/em>.\nWhen we have to flip directions like this to compare <code>T<\/code>, we say that <code>Setter<\/code> is <em>contravariant<\/em> on <code>T<\/code>.<\/p>\n<p>With TypeScript 4.7, we&#8217;re now able to <em>explicitly<\/em> specify variance on type parameters.<\/p>\n<p>So now, if we want to make it explicit that <code>Getter<\/code> is covariant on <code>T<\/code>, we can now give it an <code>out<\/code> modifier.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Getter<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">out<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; = () <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p>And similarly, if we also want to make it explicit that <code>Setter<\/code> is contravariant on <code>T<\/code>, we can give it an <code>in<\/code> modifier.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Setter<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">in<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; = (<\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p><code>out<\/code> and <code>in<\/code> are used here because a type parameter&#8217;s variance depends on whether it&#8217;s used in an <em>output<\/em> or an <em>input<\/em>.\nInstead of thinking about variance, you can just think about if <code>T<\/code> is used in output and input positions.<\/p>\n<p>There are also cases for using both <code>in<\/code> and <code>out<\/code>.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">State<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">in<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">out<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">get<\/span><span style=\"color: #000000;\">: () <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">set<\/span><span style=\"color: #000000;\">: (<\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>When a <code>T<\/code> is used in both an output and input position, it becomes <em>invariant<\/em>.\nTwo different <code>State&lt;T&gt;<\/code>s can&#8217;t be interchanged unless their <code>T<\/code>s are the same.\nIn other words, <code>State&lt;Dog&gt;<\/code> and <code>State&lt;Animal&gt;<\/code> aren&#8217;t substitutable for the other.<\/p>\n<p>Now technically speaking, in a purely structural type system, type parameters and their variance don&#8217;t really matter &#8211; you can just plug in types in place of each type parameter and check whether each matching member is structurally compatible.\nSo if TypeScript uses a structural type system, why are we interested in the variance of type parameters?\nAnd why might we ever want to annotate them?<\/p>\n<p>One reason is that it can be a useful for a reader to explicitly see how a type parameter is used at a glance.\nFor much more complex types, it can be difficult to tell whether a type is meant to be read, written, or both.\nTypeScript will also help us out if we forget to mention how that type parameter is used.\nAs an example, if we forgot to specify both <code>in<\/code> and <code>out<\/code> on <code>State<\/code>, we&#8217;d get an error.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">State<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">out<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/          ~~~~~<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ error!<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Type 'State&lt;sub-T&gt;' is not assignable to type 'State&lt;super-T&gt;' as implied by variance annotation.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/   Types of property 'set' are incompatible.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/     Type '(value: sub-T) =&gt; void' is not assignable to type '(value: super-T) =&gt; void'.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/       Types of parameters 'value' and 'value' are incompatible.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/         Type 'super-T' is not assignable to type 'sub-T'.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">get<\/span><span style=\"color: #000000;\">: () <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #795E26;\">set<\/span><span style=\"color: #000000;\">: (<\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>Another reason is precision and speed!\nTypeScript already tries to infer the variance of type parameters as an optimization.\nBy doing this, it can type-check larger structural types in a reasonable amount of time.\nCalculating variance ahead of time allows the type-checker to skip deeper comparisons and just compare type arguments which can be <em>much<\/em> faster than comparing the full structure of a type over and over again.\nBut often there are cases where this calculation is still fairly expensive, and the calculation may find circularities that can&#8217;t be accurately resolved, meaning there&#8217;s no clear answer for the variance of a type.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Foo<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt; = {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">f<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Bar<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Bar<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">U<\/span><span style=\"color: #000000;\">&gt; = (<\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Baz<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">U<\/span><span style=\"color: #000000;\">[]&gt;) <\/span><span style=\"color: #0000FF;\">=&gt;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">void<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Baz<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">V<\/span><span style=\"color: #000000;\">&gt; = {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Foo<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">V<\/span><span style=\"color: #000000;\">[]&gt;;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #0000FF;\">declare<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">let<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">foo1<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Foo<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">unknown<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n<span style=\"color: #0000FF;\">declare<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">let<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">foo2<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">Foo<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">&gt;;<\/span>\r\n\r\n<span style=\"color: #001080;\">foo1<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">foo2<\/span><span style=\"color: #000000;\">;  <\/span><span style=\"color: #008000;\">\/\/ Should be an error but isn't \u274c<\/span>\r\n<span style=\"color: #001080;\">foo2<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">foo1<\/span><span style=\"color: #000000;\">;  <\/span><span style=\"color: #008000;\">\/\/ Error - correct \u2705<\/span>\r\n<\/code><\/pre>\n<p>Providing an explicit annotation can speed up type-checking at these circularities and provide better accuracy.\nFor instance, marking <code>T<\/code> as invariant in the above example can help stop the problematic assignment..<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #A31515;\">- type Foo&lt;T&gt; = {<\/span>\r\n<span style=\"color: #098658;\">+ type Foo&lt;in out T&gt; = {<\/span>\r\n<span style=\"color: #000000;\">      x: T;<\/span>\r\n<span style=\"color: #000000;\">      f: Bar&lt;T&gt;;<\/span>\r\n<span style=\"color: #000000;\">  }<\/span>\r\n<\/code><\/pre>\n<p>We don&#8217;t necessarily recommend annotating every type parameter with its variance;\nFor example, it&#8217;s possible (but not recommended) to make variance a little stricter than is necessary, so TypeScript won&#8217;t stop you from marking something as invariant if it&#8217;s really just covariant, contravariant, or even independent.\nSo if you do choose to add explicit variance markers, we would encourage thoughtful and precise use of them.<\/p>\n<p>But if you&#8217;re working with deeply recursive types, especially if you&#8217;re a library author, you may be interested in using these annotations to the benefit of your users, providing wins in both both accuracy and type-checking speed, which can even affect their code editing experience.\nDetermining when variance calculation is a bottleneck on type-checking time can be done experimentally, and determined using tooling like our <a href=\"https:\/\/github.com\/microsoft\/typescript-analyze-trace\">analyze-trace<\/a> utility.<\/p>\n<p>For more details on this feature, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48240\">read up on the pull request<\/a>.<\/p>\n<h2><a name=\"resolution-customization-with-modulesuffixes\"><\/a> Resolution Customization with <code>moduleSuffixes<\/code><\/h2>\n<p>TypeScript 4.7 now supports a <code>moduleSuffixes<\/code> option to customize how module specifiers are looked up.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000000;\">{<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0451A5;\">&quot;compilerOptions&quot;<\/span><span style=\"color: #000000;\">: {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #0451A5;\">&quot;moduleSuffixes&quot;<\/span><span style=\"color: #000000;\">: [<\/span><span style=\"color: #A31515;\">&quot;.ios&quot;<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #A31515;\">&quot;.native&quot;<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #A31515;\">&quot;&quot;<\/span><span style=\"color: #000000;\">]<\/span>\r\n<span style=\"color: #000000;\">    }<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>Given the above configuration, an import like the following&#8230;<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">foo<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/foo&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<\/code><\/pre>\n<p>will try to look at the the relative files <code>.\/foo.ios.ts<\/code>, <code>.\/foo.native.ts<\/code>, and finally <code>.\/foo.ts<\/code>.<\/p>\n<aside>\n<p>Note that the empty string <code>&quot;&quot;<\/code> in <code>moduleSuffixes<\/code> is necessary for TypeScript to also look-up <code>.\/foo.ts<\/code>.\nIn a sense, the default value for <code>moduleSuffixes<\/code> is <code>[&quot;&quot;]<\/code>.<\/p>\n<\/aside>\n<p>This feature can be useful for React Native projects where each target platform can use a separate <code>tsconfig.json<\/code> with differing <code>moduleSuffixes<\/code>.<\/p>\n<p><a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48189\">The <code>moduleSuffixes<\/code> option<\/a> was contributed thanks to <a href=\"https:\/\/github.com\/afoxman\">Adam Foxman<\/a>!<\/p>\n<h2><a name=\"resolution-mode\"><\/a> resolution-mode<\/h2>\n<p>With Node&#8217;s ECMAScript resolution, the mode of the containing file and the syntax you use determines how imports are resolved;\nhowever it would be useful to reference the types of a CommonJS module from an ECMAScript module, or vice-versa.<\/p>\n<p>TypeScript now allows <code>\/\/\/ &lt;reference types=&quot;...&quot; \/&gt;<\/code> directives.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/\/ &lt;reference types=&quot;pkg&quot; resolution-mode=&quot;require&quot; \/&gt;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ or<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/\/ &lt;reference types=&quot;pkg&quot; resolution-mode=&quot;import&quot; \/&gt;<\/span>\r\n<\/code><\/pre>\n<p>Additionally, in nightly versions of TypeScript, <code>import type<\/code> can specify an import assertion to achieve something similar.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ Resolve `pkg` as if we were importing with a `require()`<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">type<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #001080;\">TypeFromRequire<\/span><span style=\"color: #000000;\"> } <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;pkg&quot;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">assert<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    &quot;<\/span><span style=\"color: #001080;\">resolution<\/span><span style=\"color: #000000;\">-<\/span><span style=\"color: #001080;\">mode<\/span><span style=\"color: #000000;\">&quot;: &quot;<\/span><span style=\"color: #001080;\">require<\/span><span style=\"color: #000000;\">&quot;<\/span>\r\n<span style=\"color: #000000;\">};<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ Resolve `pkg` as if we were importing with an `import`<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">type<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #001080;\">TypeFromImport<\/span><span style=\"color: #000000;\"> } <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;pkg&quot;<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">assert<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    &quot;<\/span><span style=\"color: #001080;\">resolution<\/span><span style=\"color: #000000;\">-<\/span><span style=\"color: #001080;\">mode<\/span><span style=\"color: #000000;\">&quot;: &quot;<\/span><span style=\"color: #001080;\">import<\/span><span style=\"color: #000000;\">&quot;<\/span>\r\n<span style=\"color: #000000;\">};<\/span>\r\n\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">MergedType<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">TypeFromRequire<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">TypeFromImport<\/span><span style=\"color: #000000;\"> {}<\/span>\r\n<\/code><\/pre>\n<p>These import assertions can also be used on <code>import()<\/code> types.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">TypeFromRequire<\/span><span style=\"color: #000000;\"> =<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">import<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;pkg&quot;<\/span><span style=\"color: #000000;\">, { <\/span><span style=\"color: #001080;\">assert:<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #A31515;\">&quot;resolution-mode&quot;<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;require&quot;<\/span><span style=\"color: #000000;\"> } }).<\/span><span style=\"color: #001080;\">TypeFromRequire<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">TypeFromImport<\/span><span style=\"color: #000000;\"> =<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">import<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">&quot;pkg&quot;<\/span><span style=\"color: #000000;\">, { <\/span><span style=\"color: #001080;\">assert:<\/span><span style=\"color: #000000;\"> { <\/span><span style=\"color: #A31515;\">&quot;resolution-mode&quot;<\/span><span style=\"color: #001080;\">:<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;import&quot;<\/span><span style=\"color: #000000;\"> } }).<\/span><span style=\"color: #001080;\">TypeFromImport<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #AF00DB;\">export<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">MergedType<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">TypeFromRequire<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">TypeFromImport<\/span><span style=\"color: #000000;\"> {}<\/span>\r\n<\/code><\/pre>\n<p>The <code>import type<\/code> and <code>import()<\/code> syntaxes only support <code>resolution-mode<\/code> in <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/nightly-builds.html\">nightly builds of TypeScript<\/a>.\nYou&#8217;ll likely get an error like<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000;\">Resolution mode assertions are unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.<\/span>\r\n<span style=\"color: #000;\"><\/span><\/code><\/pre>\n<p>If you do find yourself using this feature in nightly versions of TypeScript, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/49055\">consider providing feedback on this issue<\/a>.<\/p>\n<p>You can see the respective changes <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47732\">for reference directives<\/a> and <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47807\">for type import assertions<\/a>.<\/p>\n<h2><a name=\"go-to-source-definition\"><\/a> Go to Source Definition<\/h2>\n<p>TypeScript 4.7 contains support for a new experimental editor command called <em>Go To Source Definition<\/em>.\nIt&#8217;s similar to <em>Go To Definition<\/em>, but it never returns results inside declaration files.\nInstead, it tries to find corresponding <em>implementation<\/em> files (like <code>.js<\/code> or <code>.ts<\/code> files), and find definitions there \u2014 even if those files are normally shadowed by <code>.d.ts<\/code> files.<\/p>\n<p>This comes in handy most often when you need to peek at the implementation of a function you&#8217;re importing from a library instead of its type declaration in a <code>.d.ts<\/code> file.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2022\/05\/go-to-source-definition-4-7-v1.gif\" alt=\"The &quot;Go to Source Definition&quot; command on a use of the yargs package jumps the editor to a index.cjs file in yargs.\"><\/p>\n<p>You can try this new command in the latest versions of Visual Studio Code.\nNote, though, that this functionality is still in preview, and there are some known limitations.\nIn some cases TypeScript uses heuristics to guess which <code>.js<\/code> file corresponds to the given result of a definition, so these results might be inaccurate.\nVisual Studio Code also doesn&#8217;t yet indicate whether a result was a guess, but it&#8217;s something we&#8217;re collaborating on.<\/p>\n<p>You can leave feedback about the feature, read about known limitations, or learn more at <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/49003\">our dedicated feedback issue<\/a>.<\/p>\n<h2><a name=\"group-aware-organize-imports\"><\/a> Group-Aware Organize Imports<\/h2>\n<p>TypeScript has an <em>Organize Imports<\/em> editor feature for both JavaScript and TypeScript.\nUnfortunately, it could be a bit of a blunt instrument, and would often naively sort your import statements.<\/p>\n<p>For instance, if you ran Organize Imports on the following file&#8230;<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ local code<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">bbb<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/bbb&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">ccc<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/ccc&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">aaa<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/aaa&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ built-ins<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">path<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;path&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">child_process<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;child_process&quot;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">fs<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;fs&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ some code...<\/span>\r\n<\/code><\/pre>\n<p>You would get something like the following<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ local code<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">child_process<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;child_process&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">fs<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;fs&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #008000;\">\/\/ built-ins<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">path<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;path&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">aaa<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/aaa&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">bbb<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/bbb&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">ccc<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/ccc&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n\r\n<span style=\"color: #008000;\">\/\/ some code...<\/span>\r\n<\/code><\/pre>\n<p>This is&#8230; not ideal.\nSure, our imports are sorted by their paths, and our comments and newlines are preserved, but not in a predictable way.\nMuch of the time, if we have our imports grouped in a specific way, then we want to keep them that way.<\/p>\n<p>TypeScript 4.7 performs Organize Imports in a group-aware manner.\nRunning it on the above code looks a little bit more like what you&#8217;d expect:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #008000;\">\/\/ local code<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">aaa<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/aaa&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">bbb<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/bbb&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">ccc<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;.\/ccc&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ built-ins<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">child_process<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;child_process&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">fs<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;fs&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">path<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;path&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #008000;\">\/\/ some code...<\/span>\r\n<\/code><\/pre>\n<p>We&#8217;d like to extend our thanks to <a href=\"https:\/\/github.com\/MQuy\">Minh Quy<\/a> who provided <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48330\">this feature<\/a>.<\/p>\n<h2><a name=\"object-method-snippet-completions\"><\/a> Object Method Snippet Completions<\/h2>\n<p>TypeScript now provides snippet completions for object literal methods.\nWhen completing members in an object, TypeScript will provide a typical completion entry for just the name of a method, along with a separate completion entry for the full method definition!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2022\/05\/object-method-completions-4-7-v2.gif\" alt=\"Completion a full method signature from an object\"><\/p>\n<p>For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48168\">see the implementing pull request<\/a>.<\/p>\n<h2><a name=\"breaking-changes\"><\/a> Breaking Changes<\/h2>\n<h3><code>lib.d.ts<\/code> Updates<\/h3>\n<p>While TypeScript strives to avoid major breaks, even small changes in the built-in libraries can cause issues.\nWe don&#8217;t expect major breaks as a result of DOM and <code>lib.d.ts<\/code> updates, but there may be some small ones.<\/p>\n<h3>Stricter Spread Checks in JSX<\/h3>\n<p>When writing a <code>...spread<\/code> in JSX, TypeScript now enforces stricter checks that the given type is actually an object.\nAs a results, values with the types <code>unknown<\/code> and <code>never<\/code> (and more rarely, just bare <code>null<\/code> and <code>undefined<\/code>) can no longer be spread into JSX elements.<\/p>\n<p>So for the following example:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #AF00DB;\">import<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">*<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">as<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">React<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #AF00DB;\">from<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">&quot;react&quot;<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #0000FF;\">interface<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Props<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">stuff<\/span><span style=\"color: #000000;\">?: <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">MyComponent<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">props<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">unknown<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #800000;\">&lt;div<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">{<\/span><span style=\"color: #000000;\">...<\/span><span style=\"color: #001080;\">props<\/span><span style=\"color: #0000FF;\">}<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #800000;\">\/&gt;<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>you&#8217;ll now receive an error like the following:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000;\">Spread types may only be created from object types.<\/span>\r\n<span style=\"color: #000;\"><\/span><\/code><\/pre>\n<p>This makes this behavior more consistent with spreads in object literals.<\/p>\n<p>For more details, <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48570\">see the change on GitHub<\/a>.<\/p>\n<h3>Stricter Checks with Template String Expressions<\/h3>\n<p>When a <code>symbol<\/code> value is used in a template string, it will trigger a runtime error in JavaScript.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">let<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">str<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #A31515;\">`hello <\/span><span style=\"color: #0000FF;\">${<\/span><span style=\"color: #267F99;\">Symbol<\/span><span style=\"color: #000000FF;\">()<\/span><span style=\"color: #0000FF;\">}<\/span><span style=\"color: #A31515;\">`<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #008000;\">\/\/ TypeError: Cannot convert a Symbol value to a string<\/span>\r\n<\/code><\/pre>\n<p>As a result, TypeScript will issue an error as well;\nhowever, TypeScript now also checks if a generic value that is constrained to a symbol in some way is used in a template string.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">logKey<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\"> | <\/span><span style=\"color: #267F99;\">symbol<\/span><span style=\"color: #000000;\">&gt;(<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\">): <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Now an error.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">`<\/span><span style=\"color: #0000FF;\">${<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #0000FF;\">}<\/span><span style=\"color: #A31515;\"> is the key`<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n\r\n<span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">get<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">K<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">keyof<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;(<\/span><span style=\"color: #001080;\">obj<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">K<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Now an error.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">`Grabbing property '<\/span><span style=\"color: #0000FF;\">${<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #0000FF;\">}<\/span><span style=\"color: #A31515;\">'.`<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">obj<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">];<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>TypeScript will now issue the following error:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #000;\">Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.<\/span>\r\n<span style=\"color: #000;\"><\/span><\/code><\/pre>\n<p>In some cases, you can get around this by wrapping the expression in a call to <code>String<\/code>, just like the error message suggests.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">logKey<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\"> | <\/span><span style=\"color: #267F99;\">symbol<\/span><span style=\"color: #000000;\">&gt;(<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\">): <\/span><span style=\"color: #267F99;\">S<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Now an error.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">`<\/span><span style=\"color: #0000FF;\">${<\/span><span style=\"color: #267F99;\">String<\/span><span style=\"color: #000000FF;\">(<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000FF;\">)<\/span><span style=\"color: #0000FF;\">}<\/span><span style=\"color: #A31515;\"> is the key`<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>In others, this error is too pedantic, and you might not ever care to even allow <code>symbol<\/code> keys when using <code>keyof<\/code>.\nIn such cases, you can switch to <code>string &amp; keyof ...<\/code>:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">get<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">K<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\"> &amp; <\/span><span style=\"color: #0000FF;\">keyof<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;(<\/span><span style=\"color: #001080;\">obj<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">K<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Now an error.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">console<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">log<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #A31515;\">`Grabbing property '<\/span><span style=\"color: #0000FF;\">${<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #0000FF;\">}<\/span><span style=\"color: #A31515;\">'.`<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">obj<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">key<\/span><span style=\"color: #000000;\">];<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>For more information, you can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/44578\">see the implementing pull request<\/a>.<\/p>\n<h3><code>readFile<\/code> Method is No Longer Optional on <code>LanguageServiceHost<\/code><\/h3>\n<p>If you&#8217;re creating <code>LanguageService<\/code> instances, then provided <code>LanguageServiceHost<\/code>s will need to provide a <code>readFile<\/code> method.\nThis change was necessary to support the new <code>moduleDetection<\/code> compiler option.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47495\">read more on the change here<\/a>.<\/p>\n<h3><code>readonly<\/code> Tuples Have a <code>readonly<\/code> <code>length<\/code> Property<\/h3>\n<p>A <code>readonly<\/code> tuple will now treat its <code>length<\/code> property as <code>readonly<\/code>.\nThis was almost never witnessable for fixed-length tuples, but was an oversight which could be observed for tuples with trailing optional and rest element types.<\/p>\n<p>As a result, the following code will now fail:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">function<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">overwriteLength<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">tuple<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #0000FF;\">readonly<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #267F99;\">string<\/span><span style=\"color: #000000;\">]) {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Now errors.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">tuple<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">length<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #098658;\">7<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>You can <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47717\">read more on this change here<\/a>.<\/p>\n<h2>What&#8217;s Next?<\/h2>\n<p>In a few weeks, we&#8217;ll roll out our stable release of TypeScript 4.7.\nBetween now and then, we expect to only address critical issues impacting the release.<\/p>\n<p>Otherwise, our team will mainly be focusing on our next version!\nTo get a sense of what we&#8217;ll be working on, you can check out the <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/49074\">TypeScript 4.8 iteration plan<\/a>.\nThat iteration plan describes planned work and target release dates which might be helpful for you to plan around.<\/p>\n<p>If you can give the release candidate a try, please do so!\nWe appreciate all the feedback we can get, so please don&#8217;t hesitate to <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/new\/choose\">reach out on our issue tracker<\/a> and let us know if you run into anything.<\/p>\n<p>Happy Hacking!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re excited to announce our Release Candidate (RC) of TypeScript 4.7! Between now and the stable release of TypeScript 4.7, we expect no further changes apart from critical bug fixes. To get started using the RC, you can get it through NuGet, or use npm with the following command: npm install typescript@rc You can [&hellip;]<\/p>\n","protected":false},"author":381,"featured_media":1797,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Today we&#8217;re excited to announce our Release Candidate (RC) of TypeScript 4.7! Between now and the stable release of TypeScript 4.7, we expect no further changes apart from critical bug fixes. To get started using the RC, you can get it through NuGet, or use npm with the following command: npm install typescript@rc You can [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/users\/381"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/comments?post=3438"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3438\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media\/1797"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media?parent=3438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=3438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=3438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}