{"id":3404,"date":"2022-04-08T11:42:27","date_gmt":"2022-04-08T19:42:27","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=3404"},"modified":"2022-04-08T14:02:55","modified_gmt":"2022-04-08T22:02:55","slug":"announcing-typescript-4-7-beta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-7-beta\/","title":{"rendered":"Announcing TypeScript 4.7 Beta"},"content":{"rendered":"<p>Today we are excited to announce the beta release of TypeScript 4.7!<\/p>\n<p>To get started using the beta, you can <!--get it [through NuGet](https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild), 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@beta<\/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-47beta\">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=\"#typeof-on-private-fields\"><code>typeof<\/code> on <code>#private<\/code> Fields<\/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=\"#groups-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=\"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>node12<\/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;nodenext&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 (and top-level <code>await<\/code> in <code>nodenext<\/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 node12<\/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 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;\">let<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">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: #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;\">FirstString<\/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;\">FirstString<\/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;\">FirstString<\/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;\">FirstString<\/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;\">FirstString<\/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;\">number<\/span><span style=\"color: #000000;\">]&gt;;<\/span>\r\n<\/code><\/pre>\n<p><code>FirstString<\/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>FirstString<\/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;\">FirstString<\/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;\">FirstString<\/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><!--\n\nWhen checking if one type is related to another, TypeScript is mostly checking for whether each type is substitutable for the other.\nFor example, let's take the following.\n\n```ts\ndeclare let getAnimal: () => Animal;\ndeclare let getDog: () => Dog;\n\n\/\/ Which of these is correct?\ngetAnimal = getDog;\ngetDog = getAnimal;\n```\n\nLet's assume `Dog`s are valid `Animal`s.\nIf that's the case, then assigning a `() => Dog` to an `() => Animal` is valid, so `getAnimal = getDog` is correct because any place you might need to get an `Animal`, it's fine to get a `Dog`.\n\nThings get confusing with parameters. \n\n```ts\ndeclare let setAnimal: (animal: Animal) => void;\ndeclare let setDog: (dog: Dog) => void;\n\n\/\/ Which of these is correct?\nsetAnimal = setDog;\nsetDog = setAnimal;\n```\n\nIn this case, if you have a function that expects `Dog`s, you can't give it arbitrary `Animal`s.\nThe direction flips, and so (under `--strictFunctionTypes`) it's only valid to assign an `(animal: Animal) => void` to a `(dog: Dog) => void`.\n\nWe can get a little more abstract with these examples to talk about them more generally.\n\n--><\/p>\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> \u2192 <code>Getter&lt;Animal&gt;<\/code> is valid, we could just check whether <code>Dog<\/code> \u2192 <code>Animal<\/code> is valid.\nBecause each type for <code>T<\/code> just gets related in the same &quot;direction&quot;, we say that this <code>Getter<\/code> is <em>covariant<\/em> on <code>T<\/code>.\nOn the other hand, checking whether <code>Setter&lt;Dog&gt;<\/code> \u2192 <code>Setter&lt;Animal&gt;<\/code> is valid involves checking whether <code>Animal<\/code> \u2192 <code>Dog<\/code> is valid.\nThat &quot;flip&quot; in direction is kind of like how in math, checking <code>-x &lt; -y<\/code> is the same as checking whether <code>y &lt; x<\/code>.\nWe say that <code>Setter<\/code> is <em>contravariant<\/em> on <code>T<\/code> when we have to flip directions.<\/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 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=\"typeof-on-private-fields\"><\/a> <code>typeof<\/code> on <code>#private<\/code> Fields<\/h2>\n<p>TypeScript 4.7 now allows us to perform <code>typeof<\/code> queries on private fields.<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #0000FF;\">class<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #267F99;\">Container<\/span><span style=\"color: #000000;\"> {<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">#data<\/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: #000000;\">    <\/span><span style=\"color: #0000FF;\">get<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">data<\/span><span style=\"color: #000000;\">(): <\/span><span style=\"color: #0000FF;\">typeof<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">this<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">#data<\/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;\">#data<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">    }<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">set<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #795E26;\">data<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">value<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #0000FF;\">typeof<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">this<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">#data<\/span><span style=\"color: #000000;\">) {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #0000FF;\">this<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">#data<\/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<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p><a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/47696\">This change<\/a> was provided courtesy of <a href=\"https:\/\/github.com\/a-tarasyuk\">Oleksandr Tarasiuk<\/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 and <code>import type<\/code> statements to specify a resolution strategy.<\/p>\n<p><code>import type<\/code> can specify an import assertion to achieve this.<\/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>Similarly, we can use <code>resolution-mode<\/code> on a <code>\/\/\/ &lt;reference types=&quot;...&quot; \/&gt;<\/code> directive.<\/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>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=\"groups-aware-organize-imports\"><\/a> Groups-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\/04\/object-method-completions-4-7.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>Type Parameters No Longer Assignable to <code>{}<\/code> in <code>strictNullChecks<\/code><\/h3>\n<p>Originally, the constraint of all type parameters in TypeScript was <code>{}<\/code> (the empty object type).\nEventually the constraint was changed to <code>unknown<\/code> which also permits <code>null<\/code> and <code>undefined<\/code>.\nOutside of <code>strictNullChecks<\/code>, these types are interchangeable, but within <code>strictNullChecks<\/code>, <code>unknown<\/code> is not assignable to <code>{}<\/code>.<\/p>\n<p>In TypeScript 4.7, under <code>strictNullChecks<\/code>, the type-checker disables a type safety hole that was maintained for backwards-compatibility, where type parameters were considered to always be assignable to <code>{}<\/code> and <code>object<\/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;\">foo<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;(<\/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: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">a<\/span><span style=\"color: #000000;\">: {} = <\/span><span style=\"color: #001080;\">x<\/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><span style=\"color: #008000;\">\/\/ Type 'T' is not assignable to type '{}'.<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">b<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">object<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">x<\/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><span style=\"color: #008000;\">\/\/ Type 'T' is not assignable to type 'object'.<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>In such cases, you may need a type assertion on <code>x<\/code>, or a constraint of <code>{}<\/code> on <code>T<\/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;\">foo<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">extends<\/span><span style=\"color: #000000;\"> {}&gt;(<\/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: #008000;\">\/\/ Works<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">a<\/span><span style=\"color: #000000;\">: {} = <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">;<\/span>\r\n\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #008000;\">\/\/ Works<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">b<\/span><span style=\"color: #000000;\">: <\/span><span style=\"color: #267F99;\">object<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>This behavior can come up in calls to<\/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;\">keysEqual<\/span><span style=\"color: #000000;\">&lt;<\/span><span style=\"color: #267F99;\">T<\/span><span style=\"color: #000000;\">&gt;(<\/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: #001080;\">y<\/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: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">xKeys<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">Object<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">keys<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">x<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #0000FF;\">const<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0070C1;\">yKeys<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #267F99;\">Object<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #795E26;\">keys<\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #001080;\">y<\/span><span style=\"color: #000000;\">);<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">if<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #001080;\">xKeys<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">length<\/span><span style=\"color: #000000;\"> !== <\/span><span style=\"color: #001080;\">yKeys<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">length<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">false<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #AF00DB;\">for<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #0000FF;\">let<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">i<\/span><span style=\"color: #000000;\"> = <\/span><span style=\"color: #098658;\">0<\/span><span style=\"color: #000000;\">; <\/span><span style=\"color: #001080;\">i<\/span><span style=\"color: #000000;\"> &lt; <\/span><span style=\"color: #001080;\">xKeys<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #001080;\">length<\/span><span style=\"color: #000000;\">; <\/span><span style=\"color: #001080;\">i<\/span><span style=\"color: #000000;\">++) {<\/span>\r\n<span style=\"color: #000000;\">        <\/span><span style=\"color: #AF00DB;\">if<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #001080;\">xKeys<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">i<\/span><span style=\"color: #000000;\">] !== <\/span><span style=\"color: #001080;\">yKeys<\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #001080;\">i<\/span><span style=\"color: #000000;\">]) <\/span><span style=\"color: #AF00DB;\">return<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">false<\/span><span style=\"color: #000000;\">;<\/span>\r\n<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;\">true<\/span><span style=\"color: #000000;\">;<\/span>\r\n<span style=\"color: #000000;\">}<\/span>\r\n<\/code><\/pre>\n<p>For the above, you might see an error message that looks like this:<\/p>\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code><span style=\"color: #001080;\">No<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">overload<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">matches<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">this<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">call<\/span><span style=\"color: #000000;\">.<\/span>\r\n<span style=\"color: #000000;\">  <\/span><span style=\"color: #001080;\">Overload<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #098658;\">1<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">of<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #098658;\">2<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #A31515;\">'(o: {}): string[]'<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #001080;\">gave<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">the<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">following<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">error<\/span><span style=\"color: #000000;\">.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">Argument<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">of<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">'T'<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">is<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">not<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">assignable<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">to<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">parameter<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">of<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">'{}'<\/span><span style=\"color: #000000;\">.<\/span>\r\n<span style=\"color: #000000;\">  <\/span><span style=\"color: #001080;\">Overload<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #098658;\">2<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">of<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #098658;\">2<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #A31515;\">'(o: object): string[]'<\/span><span style=\"color: #000000;\">, <\/span><span style=\"color: #001080;\">gave<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">the<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">following<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">error<\/span><span style=\"color: #000000;\">.<\/span>\r\n<span style=\"color: #000000;\">    <\/span><span style=\"color: #001080;\">Argument<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">of<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">'T'<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">is<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">not<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">assignable<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">to<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">parameter<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #0000FF;\">of<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #001080;\">type<\/span><span style=\"color: #000000;\"> <\/span><span style=\"color: #A31515;\">'object'<\/span><span style=\"color: #000000;\">.<\/span>\r\n<\/code><\/pre>\n<p>For more information, take a look at <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/pull\/48366\">the breaking PR here<\/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 the coming weeks, we&#8217;ll be polishing TypeScript 4.7 to get it ready for a Release Candidate, making sure that everything works just as you would expect.\nIf you&#8217;d like to plan around our release schedule, our target release dates are available on the <a href=\"https:\/\/github.com\/microsoft\/TypeScript\/issues\/48027\">TypeScript 4.7 iteration plan<\/a>.<\/p>\n<p>We hope that this release brings some exciting and helpful features to make coding a joy.<\/p>\n<p>Happy Hacking!<\/p>\n<p>&#8211; Daniel Rosenwasser and the TypeScript Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we are excited to announce the beta release of TypeScript 4.7! To get started using the beta, you can use npm with the following command: npm install typescript@beta You can also get editor support by Downloading for Visual Studio 2022\/2019 Following directions for Visual Studio Code and Sublime Text 3. Here&#8217;s a quick list [&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-3404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Today we are excited to announce the beta release of TypeScript 4.7! To get started using the beta, you can use npm with the following command: npm install typescript@beta You can also get editor support by Downloading for Visual Studio 2022\/2019 Following directions for Visual Studio Code and Sublime Text 3. Here&#8217;s a quick list [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3404","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=3404"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3404\/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=3404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=3404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=3404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}