{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/release-notes/typescript-2-9.html","result":{"data":{"allSitePage":{"nodes":[{"path":"/dev-404-page/"},{"path":"/docs/handbook/advanced-types.html"},{"path":"/docs/handbook/basic-types.html"},{"path":"/docs/handbook/classes.html"},{"path":"/docs/handbook/compiler-options-in-msbuild.html"},{"path":"/docs/handbook/compiler-options.html"},{"path":"/docs/handbook/configuring-watch.html"},{"path":"/docs/handbook/declaration-merging.html"},{"path":"/docs/handbook/decorators.html"},{"path":"/docs/handbook/enums.html"},{"path":"/docs/handbook/functions.html"},{"path":"/docs/handbook/generics.html"},{"path":"/docs/handbook/integrating-with-build-tools.html"},{"path":"/docs/handbook/interfaces.html"},{"path":"/docs/handbook/iterators-and-generators.html"},{"path":"/docs/handbook/jsdoc-supported-types.html"},{"path":"/docs/handbook/jsx.html"},{"path":"/docs/handbook/literal-types.html"},{"path":"/docs/handbook/mixins.html"},{"path":"/docs/handbook/module-resolution.html"},{"path":"/docs/handbook/modules.html"},{"path":"/docs/handbook/namespaces-and-modules.html"},{"path":"/docs/handbook/namespaces.html"},{"path":"/docs/handbook/nightly-builds.html"},{"path":"/docs/handbook/project-references.html"},{"path":"/docs/handbook/symbols.html"},{"path":"/docs/handbook/"},{"path":"/docs/handbook/triple-slash-directives.html"},{"path":"/docs/handbook/type-checking-javascript-files.html"},{"path":"/docs/handbook/type-compatibility.html"},{"path":"/docs/handbook/type-inference.html"},{"path":"/docs/handbook/unions-and-intersections.html"},{"path":"/docs/handbook/utility-types.html"},{"path":"/docs/handbook/variable-declarations.html"},{"path":"/docs/handbook/writing-declaration-files.html"},{"path":"/docs/handbook/declaration-files/by-example.html"},{"path":"/docs/handbook/declaration-files/consumption.html"},{"path":"/docs/handbook/declaration-files/deep-dive.html"},{"path":"/docs/handbook/declaration-files/do-s-and-don-ts.html"},{"path":"/docs/handbook/declaration-files/introduction.html"},{"path":"/docs/handbook/declaration-files/library-structures.html"},{"path":"/docs/handbook/declaration-files/publishing.html"},{"path":"/docs/handbook/declaration-files/templates.html"},{"path":"/docs/handbook/release-notes/typescript-1-1.html"},{"path":"/docs/handbook/release-notes/typescript-1-3.html"},{"path":"/docs/handbook/release-notes/typescript-1-4.html"},{"path":"/docs/handbook/release-notes/typescript-1-5.html"},{"path":"/docs/handbook/release-notes/typescript-1-6.html"},{"path":"/docs/handbook/release-notes/typescript-1-7.html"},{"path":"/docs/handbook/release-notes/typescript-1-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-0.html"},{"path":"/docs/handbook/release-notes/typescript-2-2.html"},{"path":"/docs/handbook/release-notes/typescript-2-1.html"},{"path":"/docs/handbook/release-notes/typescript-2-3.html"},{"path":"/docs/handbook/release-notes/typescript-2-4.html"},{"path":"/docs/handbook/release-notes/typescript-2-5.html"},{"path":"/docs/handbook/release-notes/typescript-2-6.html"},{"path":"/docs/handbook/release-notes/typescript-2-7.html"},{"path":"/docs/handbook/release-notes/typescript-2-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-9.html"},{"path":"/docs/handbook/release-notes/typescript-3-0.html"},{"path":"/docs/handbook/release-notes/typescript-3-1.html"},{"path":"/docs/handbook/release-notes/typescript-3-2.html"},{"path":"/docs/handbook/release-notes/typescript-3-3.html"},{"path":"/docs/handbook/release-notes/typescript-3-4.html"},{"path":"/docs/handbook/release-notes/typescript-3-5.html"},{"path":"/docs/handbook/release-notes/typescript-3-6.html"},{"path":"/docs/handbook/release-notes/typescript-3-7.html"},{"path":"/docs/handbook/release-notes/typescript-3-8.html"},{"path":"/docs/handbook/asp-net-core.html"},{"path":"/docs/handbook/angular.html"},{"path":"/docs/handbook/dom-manipulation.html"},{"path":"/docs/handbook/gulp.html"},{"path":"/docs/handbook/migrating-from-javascript.html"},{"path":"/docs/handbook/react-&-webpack.html"},{"path":"/docs/handbook/react.html"},{"path":"/docs/handbook/typescript-in-5-minutes-func.html"},{"path":"/docs/handbook/typescript-in-5-minutes.html"},{"path":"/docs/handbook/typescript-in-5-minutes-oop.html"},{"path":"/docs/handbook/typescript-from-scratch.html"},{"path":"/docs/handbook/typescript-tooling-in-5-minutes.html"},{"path":"/docs/handbook/tsconfig-json.html"},{"path":"/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-class-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-function-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-d-ts.html"},{"path":"/docs/handbook/release-notes/overview.html"},{"path":"/tsconfig"},{"path":"/en/tsconfig"},{"path":"/ja/tsconfig"},{"path":"/vo/tsconfig"},{"path":"/play"},{"path":"/en/play"},{"path":"/es/play"},{"path":"/vo/play"},{"path":"/zh/play"},{"path":"/ja/play"},{"path":"/play/3-7/fixits/big-number-literals.ts"},{"path":"/play/3-7/fixits/const-to-let.ts"},{"path":"/play/3-7/fixits/infer-from-usage-changes.ts"},{"path":"/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/play/3-7/syntax-and-messaging/nullish-coalescing.ts"},{"path":"/play/3-7/syntax-and-messaging/optional-chaining.ts"},{"path":"/play/3-7/types-and-code-flow/assertion-functions.ts"},{"path":"/play/3-7/types-and-code-flow/recursive-type-references.ts"},{"path":"/play/3-7/types-and-code-flow/uncalled-function-checks.ts"},{"path":"/play/3-8/breaking-changes/checking-unions-with-index-signatures.ts"},{"path":"/play/3-8/jsdoc-improvements/accessibility-modifiers.js"},{"path":"/play/3-8/syntax-and-messaging/export-modules-from.ts"},{"path":"/play/3-8/syntax-and-messaging/private-class-fields.ts"},{"path":"/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/play/javascript/external-apis/typescript-with-node.js"},{"path":"/play/javascript/external-apis/typescript-with-web.js"},{"path":"/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/play/javascript/helping-with-javascript/errors.ts"},{"path":"/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/play/javascript/javascript-essentials/functions.ts"},{"path":"/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/play/javascript/modern-javascript/async-await.ts"},{"path":"/play/javascript/modern-javascript/immutability.ts"},{"path":"/play/javascript/modern-javascript/import-export.ts"},{"path":"/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/play/javascript/working-with-classes/classes-101.ts"},{"path":"/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/play/javascript/working-with-classes/mixins.ts"},{"path":"/play/javascript/working-with-classes/this.ts"},{"path":"/play/playground/config/javascript-playgrounds.js"},{"path":"/play/playground/config/new-compiler-defaults.ts"},{"path":"/play/playground/language/automatic-type-acquisition.ts"},{"path":"/play/playground/language/fixits.ts"},{"path":"/play/playground/tooling/mobile-support.ts"},{"path":"/play/playground/tooling/sharable-urls.ts"},{"path":"/play/playground/tooling/typescript-versions.ts"},{"path":"/play/typescript/language/soundness.ts"},{"path":"/play/typescript/language/structural-typing.ts"},{"path":"/play/typescript/language/type-guards.ts"},{"path":"/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/play/typescript/language-extensions/enums.ts"},{"path":"/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/play/typescript/meta-types/conditional-types.ts"},{"path":"/play/typescript/meta-types/discriminate-types.ts"},{"path":"/play/typescript/meta-types/indexed-types.ts"},{"path":"/play/typescript/meta-types/mapped-types.ts"},{"path":"/play/typescript/primitives/any.ts"},{"path":"/play/typescript/primitives/literals.ts"},{"path":"/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/play/typescript/primitives/unknown-and-never.ts"},{"path":"/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/play/typescript/type-primitives/nullable-types.ts"},{"path":"/play/typescript/type-primitives/tuples.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-node.js"},{"path":"/es/play/javascript/external-apis/typescript-with-web.js"},{"path":"/es/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/es/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/es/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/es/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/es/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/es/play/typescript/type-primitives/nullable-types.ts"},{"path":"/es/play/typescript/type-primitives/tuples.ts"},{"path":"/ja/play/typescript/language-extensions/enums.ts"},{"path":"/ja/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/ja/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/ja/play/typescript/primitives/any.ts"},{"path":"/ja/play/typescript/primitives/literals.ts"},{"path":"/ja/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/ja/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/vo/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/vo/play/javascript/javascript-essentials/functions.ts"},{"path":"/vo/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/vo/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-node.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-web.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/zh/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/zh/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/zh/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/zh/play/javascript/helping-with-javascript/errors.ts"},{"path":"/zh/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/zh/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/zh/play/javascript/javascript-essentials/functions.ts"},{"path":"/zh/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/zh/play/javascript/modern-javascript/import-export.ts"},{"path":"/zh/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/zh/play/javascript/working-with-classes/classes-101.ts"},{"path":"/zh/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/zh/play/javascript/working-with-classes/mixins.ts"},{"path":"/zh/play/javascript/working-with-classes/this.ts"},{"path":"/zh/play/playground/config/javascript-playgrounds.js"},{"path":"/zh/play/playground/config/new-compiler-defaults.ts"},{"path":"/zh/play/playground/language/automatic-type-acquisition.ts"},{"path":"/zh/play/playground/language/fixits.ts"},{"path":"/zh/play/playground/tooling/mobile-support.ts"},{"path":"/zh/play/playground/tooling/sharable-urls.ts"},{"path":"/zh/play/playground/tooling/typescript-versions.ts"},{"path":"/zh/play/typescript/language/soundness.ts"},{"path":"/zh/play/typescript/language/structural-typing.ts"},{"path":"/zh/play/typescript/language/type-guards.ts"},{"path":"/zh/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/zh/play/typescript/language-extensions/enums.ts"},{"path":"/zh/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/zh/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/zh/play/typescript/meta-types/conditional-types.ts"},{"path":"/zh/play/typescript/meta-types/discriminate-types.ts"},{"path":"/zh/play/typescript/meta-types/indexed-types.ts"},{"path":"/zh/play/typescript/meta-types/mapped-types.ts"},{"path":"/zh/play/typescript/primitives/any.ts"},{"path":"/zh/play/typescript/primitives/literals.ts"},{"path":"/zh/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/zh/play/typescript/primitives/unknown-and-never.ts"},{"path":"/zh/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/zh/play/typescript/type-primitives/nullable-types.ts"},{"path":"/zh/play/typescript/type-primitives/tuples.ts"},{"path":"/zh/play/javascript/modern-javascript/immutability.ts"},{"path":"/zh/play/javascript/modern-javascript/async-await.ts"},{"path":"/zh/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/community"},{"path":"/es/community"},{"path":"/ja/community"},{"path":"/vo/community"},{"path":"/zh/community"},{"path":"/download"},{"path":"/es/download"},{"path":"/ja/download"},{"path":"/vo/download"},{"path":"/zh/download"},{"path":"/empty"},{"path":"/es/empty"},{"path":"/ja/empty"},{"path":"/vo/empty"},{"path":"/zh/empty"},{"path":"/"},{"path":"/es/"},{"path":"/ja/"},{"path":"/vo/"},{"path":"/zh/"},{"path":"/tools"},{"path":"/es/tools"},{"path":"/ja/tools"},{"path":"/vo/tools"},{"path":"/zh/tools"},{"path":"/why-create-typescript"},{"path":"/es/why-create-typescript"},{"path":"/ja/why-create-typescript"},{"path":"/vo/why-create-typescript"},{"path":"/zh/why-create-typescript"},{"path":"/docs/home"},{"path":"/es/docs/home"},{"path":"/ja/docs/home"},{"path":"/vo/docs/home"},{"path":"/zh/docs/home"},{"path":"/dev/playground-plugins/"},{"path":"/dev/sandbox/"},{"path":"/dev/twoslash/"},{"path":"/dev/typescript-vfs/"}]},"markdownRemark":{"id":"00d39b26-81dd-590d-a3d5-7a02473c2439","excerpt":"Support number and symbol named properties with keyof and mapped types TypeScript 2.9 adds support for number and symbol named properties in index types and…","html":"<h2 id=\"support-number-and-symbol-named-properties-with-keyof-and-mapped-types\" style=\"position:relative;\"><a href=\"#support-number-and-symbol-named-properties-with-keyof-and-mapped-types\" aria-label=\"support number and symbol named properties with keyof and mapped types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Support <code>number</code> and <code>symbol</code> named properties with <code>keyof</code> and mapped types</h2>\n<p>TypeScript 2.9 adds support for <code>number</code> and <code>symbol</code> named properties in index types and mapped types.\nPreviously, the <code>keyof</code> operator and mapped types only supported <code>string</code> named properties.</p>\n<p>Changes include:</p>\n<ul>\n<li>An index type <code>keyof T</code> for some type <code>T</code> is a subtype of <code>string | number | symbol</code>.</li>\n<li>A mapped type <code>{ [P in K]: XXX }</code> permits any <code>K</code> assignable to <code>string | number | symbol</code>.</li>\n<li>In a <code>for...in</code> statement for an object of a generic type <code>T</code>, the inferred type of the iteration variable was previously <code>keyof T</code> but is now <code>Extract&#x3C;keyof T, string></code>. (In other words, the subset of <code>keyof T</code> that includes only string-like values.)</li>\n</ul>\n<p>Given an object type <code>X</code>, <code>keyof X</code> is resolved as follows:</p>\n<ul>\n<li>If <code>X</code> contains a string index signature, <code>keyof X</code> is a union of <code>string</code>, <code>number</code>, and the literal types representing symbol-like properties, otherwise</li>\n<li>If <code>X</code> contains a numeric index signature, <code>keyof X</code> is a union of <code>number</code> and the literal types representing string-like and symbol-like properties, otherwise</li>\n<li><code>keyof X</code> is a union of the literal types representing string-like, number-like, and symbol-like properties.</li>\n</ul>\n<p>Where:</p>\n<ul>\n<li>String-like properties of an object type are those declared using an identifier, a string literal, or a computed property name of a string literal type.</li>\n<li>Number-like properties of an object type are those declared using a numeric literal or computed property name of a numeric literal type.</li>\n<li>Symbol-like properties of an object type are those declared using a computed property name of a unique symbol type.</li>\n</ul>\n<p>In a mapped type <code>{ [P in K]: XXX }</code>, each string literal type in <code>K</code> introduces a property with a string name, each numeric literal type in <code>K</code> introduces a property with a numeric name, and each unique symbol type in <code>K</code> introduces a property with a unique symbol name.\nFurthermore, if <code>K</code> includes type <code>string</code>, a string index signature is introduced, and if <code>K</code> includes type <code>number</code>, a numeric index signature is introduced.</p>\n<h5 id=\"example\" style=\"position:relative;\"><a href=\"#example\" aria-label=\"example permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> c = </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> d = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> e = Symbol();</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E1 { A, B, C }</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E2 { A = </span><span style=\"color: #A31515\">\"A\"</span><span style=\"color: #000000\">, B = </span><span style=\"color: #A31515\">\"B\"</span><span style=\"color: #000000\">, C = </span><span style=\"color: #A31515\">\"C\"</span><span style=\"color: #000000\"> }</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Foo = {</span>\n<span style=\"color: #000000\">    a: string;       </span><span style=\"color: #008000\">// String-like name</span>\n<span style=\"color: #000000\">    5: string;       </span><span style=\"color: #008000\">// Number-like name</span>\n<span style=\"color: #000000\">    [c]: string;     </span><span style=\"color: #008000\">// String-like name</span>\n<span style=\"color: #000000\">    [d]: string;     </span><span style=\"color: #008000\">// Number-like name</span>\n<span style=\"color: #000000\">    [e]: string;     </span><span style=\"color: #008000\">// Symbol-like name</span>\n<span style=\"color: #000000\">    [E1.A]: string;  </span><span style=\"color: #008000\">// Number-like name</span>\n<span style=\"color: #000000\">    [E2.A]: string;  </span><span style=\"color: #008000\">// String-like name</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> K1 = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> Foo;  </span><span style=\"color: #008000\">// \"a\" | 5 | \"c\" | 10 | typeof e | E1.A | E2.A</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> K2 = Extract&lt;</span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> Foo, string&gt;;  </span><span style=\"color: #008000\">// \"a\" | \"c\" | E2.A</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> K3 = Extract&lt;</span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> Foo, number&gt;;  </span><span style=\"color: #008000\">// 5 | 10 | E1.A</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> K4 = Extract&lt;</span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> Foo, symbol&gt;;  </span><span style=\"color: #008000\">// typeof e</span></code></div></pre>\n<p>Since <code>keyof</code> now reflects the presence of a numeric index signature by including type <code>number</code> in the key type, mapped types such as <code>Partial&#x3C;T></code> and <code>Readonly&#x3C;T></code> work correctly when applied to object types with numeric index signatures:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Arrayish&lt;T&gt; = {</span>\n<span style=\"color: #000000\">    length: number;</span>\n<span style=\"color: #000000\">    [x: number]: T;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> ReadonlyArrayish&lt;T&gt; = Readonly&lt;Arrayish&lt;T&gt;&gt;;</span>\n\n<span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> map: ReadonlyArrayish&lt;string&gt;;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> n = map.length;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = map[</span><span style=\"color: #09835A\">123</span><span style=\"color: #000000\">];  </span><span style=\"color: #008000\">// Previously of type any (or an error with --noImplicitAny)</span></code></div></pre>\n<p>Furthermore, with the <code>keyof</code> operator’s support for <code>number</code> and <code>symbol</code> named keys, it is now possible to abstract over access to properties of objects that are indexed by numeric literals (such as numeric enum types) and unique symbols.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Enum { A, B, C }</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> enumToStringMap = {</span>\n<span style=\"color: #000000\">    [Enum.A]: </span><span style=\"color: #A31515\">\"Name A\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">    [Enum.B]: </span><span style=\"color: #A31515\">\"Name B\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">    [Enum.C]: </span><span style=\"color: #A31515\">\"Name C\"</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> sym1 = Symbol();</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> sym2 = Symbol();</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> sym3 = Symbol();</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> symbolToNumberMap = {</span>\n<span style=\"color: #000000\">    [sym1]: </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">    [sym2]: </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">    [sym3]: </span><span style=\"color: #09835A\">3</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> KE = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> enumToStringMap;     </span><span style=\"color: #008000\">// Enum (i.e. Enum.A | Enum.B | Enum.C)</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> KS = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> symbolToNumberMap;   </span><span style=\"color: #008000\">// typeof sym1 | typeof sym2 | typeof sym3</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> getValue&lt;T, K </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> T&gt;(obj: T, key: K): T[K] {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> obj[key];</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x1 = getValue(enumToStringMap, Enum.C);  </span><span style=\"color: #008000\">// Returns \"Name C\"</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x2 = getValue(symbolToNumberMap, sym3);  </span><span style=\"color: #008000\">// Returns 3</span></code></div></pre>\n<p>This is a breaking change; previously, the <code>keyof</code> operator and mapped types only supported <code>string</code> named properties.\nCode that assumed values typed with <code>keyof T</code> were always <code>string</code>s, will now be flagged as error.</p>\n<h5 id=\"example-1\" style=\"position:relative;\"><a href=\"#example-1\" aria-label=\"example 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> useKey&lt;T, K </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> T&gt;(o: T, k: K) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> name: string = k;  </span><span style=\"color: #008000\">// Error: keyof T is not assignable to string</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h4 id=\"recommendations\" style=\"position:relative;\"><a href=\"#recommendations\" aria-label=\"recommendations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recommendations</h4>\n<ul>\n<li>\n<p>If your functions are only able to handle string named property keys, use <code>Extract&#x3C;keyof T, string></code> in the declaration:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> useKey&lt;T, K </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> Extract&lt;</span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> T, string&gt;&gt;(o: T, k: K) {</span>\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> name: string = k;  </span><span style=\"color: #008000\">// OK</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n</li>\n<li>\n<p>If your functions are open to handling all property keys, then the changes should be done down-stream:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> useKey&lt;T, K </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> T&gt;(o: T, k: K) {</span>\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> name: string | number | symbol = k;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n</li>\n<li>Otherwise use <code>--keyofStringsOnly</code> compiler option to disable the new behavior.</li>\n</ul>\n<h2 id=\"generic-type-arguments-in-jsx-elements\" style=\"position:relative;\"><a href=\"#generic-type-arguments-in-jsx-elements\" aria-label=\"generic type arguments in jsx elements permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generic type arguments in JSX elements</h2>\n<p>JSX elements now allow passing type arguments to generic components.</p>\n<h5 id=\"example-2\" style=\"position:relative;\"><a href=\"#example-2\" aria-label=\"example 2 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> GenericComponent&lt;P&gt; </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> React.Component&lt;P&gt; {</span>\n<span style=\"color: #000000\">    internalProp: P;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Props = { a: number; b: string; };</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> x = &lt;GenericComponent&lt;Props&gt; a={10} b=</span><span style=\"color: #A31515\">\"hi\"</span><span style=\"color: #000000\">/&gt;; </span><span style=\"color: #008000\">// OK</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> y = &lt;GenericComponent&lt;Props&gt; a={10} b={20} /&gt;; </span><span style=\"color: #008000\">// Error</span></code></div></pre>\n<h2 id=\"generic-type-arguments-in-generic-tagged-templates\" style=\"position:relative;\"><a href=\"#generic-type-arguments-in-generic-tagged-templates\" aria-label=\"generic type arguments in generic tagged templates permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generic type arguments in generic tagged templates</h2>\n<p>Tagged templates are a form of invocation introduced in ECMAScript 2015.\nLike call expressions, generic functions may be used in a tagged template and TypeScript will infer the type arguments utilized.</p>\n<p>TypeScript 2.9  allows passing generic type arguments to tagged template strings.</p>\n<h5 id=\"example-3\" style=\"position:relative;\"><a href=\"#example-3\" aria-label=\"example 3 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> styledComponent&lt;Props&gt;(strs: TemplateStringsArray): Component&lt;Props&gt;;</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> MyProps {</span>\n<span style=\"color: #000000\">  name: string;</span>\n<span style=\"color: #000000\">  age: number;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">styledComponent&lt;MyProps&gt; </span><span style=\"color: #A31515\">`</span>\n<span style=\"color: #A31515\">  font-size: 1.5em;</span>\n<span style=\"color: #A31515\">  text-align: center;</span>\n<span style=\"color: #A31515\">  color: palevioletred;</span>\n<span style=\"color: #A31515\">`</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> tag&lt;T&gt;(strs: TemplateStringsArray, ...args: T[]): T;</span>\n\n<span style=\"color: #008000\">// inference fails because 'number' and 'string' are both candidates that conflict</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a = tag&lt;string | number&gt; </span><span style=\"color: #A31515\">`</span><span style=\"color: #0000FF\">${</span><span style=\"color: #09835A\">100</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\"> </span><span style=\"color: #0000FF\">${</span><span style=\"color: #A31515\">\"hello\"</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">;</span></code></div></pre>\n<h2 id=\"import-types\" style=\"position:relative;\"><a href=\"#import-types\" aria-label=\"import types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>import</code> types</h2>\n<p>Modules can import types declared in other modules. But non-module global scripts cannot access types declared in modules. Enter <code>import</code> types.</p>\n<p>Using <code>import(\"mod\")</code> in a type annotation allows for reaching in a module and accessing its exported declaration without importing it.</p>\n<h5 id=\"example-4\" style=\"position:relative;\"><a href=\"#example-4\" aria-label=\"example 4 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<p>Given a declaration of a class <code>Pet</code> in a module file:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// module.d.ts</span>\n\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Pet {</span>\n<span style=\"color: #000000\">   name: string;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Can be used in a non-module file <code>global-script.ts</code>:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// global-script.ts</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> adopt(p: import(</span><span style=\"color: #A31515\">\"./module\"</span><span style=\"color: #000000\">).Pet) {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">`Adopting </span><span style=\"color: #0000FF\">${</span><span style=\"color: #A31515\">p.name</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">...`</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>This also works in JSDoc comments to refer to types from other modules in <code>.js</code>:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #008000\">// a.js</span>\n\n<span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * </span><span style=\"color: #0000FF\">@param</span><span style=\"color: #008000\"> p { import(\"./module\").Pet }</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> walk(p) {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">`Walking ${p.name}...`</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h2 id=\"relaxing-declaration-emit-visiblity-rules\" style=\"position:relative;\"><a href=\"#relaxing-declaration-emit-visiblity-rules\" aria-label=\"relaxing declaration emit visiblity rules permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Relaxing declaration emit visiblity rules</h2>\n<p>With <code>import</code> types available, many of the visibility errors reported during declaration file generation can be handled by the compiler without the need to change the input.</p>\n<p>For instance:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> { createHash } </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"crypto\"</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> hash = createHash(</span><span style=\"color: #A31515\">\"sha256\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #008000\">//           ^^^^</span>\n<span style=\"color: #008000\">// Exported variable 'hash' has or is using name 'Hash' from external module \"crypto\" but cannot be named.</span></code></div></pre>\n<p>With TypeScript 2.9, no errors are reported, and now the generated file looks like:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> hash: import(</span><span style=\"color: #A31515\">\"crypto\"</span><span style=\"color: #000000\">).Hash;</span></code></div></pre>\n<h2 id=\"support-for-importmeta\" style=\"position:relative;\"><a href=\"#support-for-importmeta\" aria-label=\"support for importmeta permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Support for <code>import.meta</code></h2>\n<p>TypeScript 2.9 introduces support for <code>import.meta</code>, a new meta-property as described by the current <a href=\"https://github.com/tc39/proposal-import-meta\">TC39 proposal</a>.</p>\n<p>The type of <code>import.meta</code> is the global <code>ImportMeta</code> type which is defined in <code>lib.es5.d.ts</code>.\nThis interface is extremely limited.\nAdding well-known properties for Node or browsers requires interface merging and possibly a global augmentation depending on the context.</p>\n<h5 id=\"example-5\" style=\"position:relative;\"><a href=\"#example-5\" aria-label=\"example 5 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<p>Assuming that <code>__dirname</code> is always available on <code>import.meta</code>, the declaration would be done through reopening <code>ImportMeta</code> interface:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// node.d.ts</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> ImportMeta {</span>\n<span style=\"color: #000000\">    __dirname: string;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>And usage would be:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">import</span><span style=\"color: #000000\">.meta.__dirname </span><span style=\"color: #008000\">// Has type 'string'</span></code></div></pre>\n<p><code>import.meta</code> is only allowed when targeting <code>ESNext</code> modules and ECMAScript targets.</p>\n<h2 id=\"new---resolvejsonmodule\" style=\"position:relative;\"><a href=\"#new---resolvejsonmodule\" aria-label=\"new   resolvejsonmodule permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>New <code>--resolveJsonModule</code></h2>\n<p>Often in Node.js applications a <code>.json</code> is needed. With TypeScript 2.9, <code>--resolveJsonModule</code> allows for importing, extracting types from and generating <code>.json</code> files.</p>\n<h5 id=\"example-6\" style=\"position:relative;\"><a href=\"#example-6\" aria-label=\"example 6 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h5>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// settings.json</span>\n\n<span style=\"color: #000000\">{</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #A31515\">\"repo\"</span><span style=\"color: #000000\">: </span><span style=\"color: #A31515\">\"TypeScript\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #A31515\">\"dry\"</span><span style=\"color: #000000\">: </span><span style=\"color: #0000FF\">false</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #A31515\">\"debug\"</span><span style=\"color: #000000\">: </span><span style=\"color: #0000FF\">false</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// a.ts</span>\n\n<span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> settings </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"./settings.json\"</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">settings.debug === </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">;  </span><span style=\"color: #008000\">// OK</span>\n<span style=\"color: #000000\">settings.dry === </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">;  </span><span style=\"color: #008000\">// Error: Operator '===' cannot be applied boolean and number</span></code></div></pre>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// tsconfig.json</span>\n\n<span style=\"color: #000000\">{</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #A31515\">\"compilerOptions\"</span><span style=\"color: #000000\">: {</span>\n<span style=\"color: #000000\">        </span><span style=\"color: #A31515\">\"module\"</span><span style=\"color: #000000\">: </span><span style=\"color: #A31515\">\"commonjs\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">        </span><span style=\"color: #A31515\">\"resolveJsonModule\"</span><span style=\"color: #000000\">: </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">        </span><span style=\"color: #A31515\">\"esModuleInterop\"</span><span style=\"color: #000000\">: </span><span style=\"color: #0000FF\">true</span>\n<span style=\"color: #000000\">    }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h2 id=\"--pretty-output-by-default\" style=\"position:relative;\"><a href=\"#--pretty-output-by-default\" aria-label=\"  pretty output by default permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>--pretty</code> output by default</h2>\n<p>Starting TypeScript 2.9 errors are displayed under <code>--pretty</code> by default if the output device is applicable for colorful text.\nTypeScript will check if the output steam has <a href=\"https://nodejs.org/api/tty.html\"><code>isTty</code></a> property set.</p>\n<p>Use <code>--pretty false</code> on the command line or set <code>\"pretty\": false</code> in your <code>tsconfig.json</code> to disable <code>--pretty</code> output.</p>\n<h2 id=\"new---declarationmap\" style=\"position:relative;\"><a href=\"#new---declarationmap\" aria-label=\"new   declarationmap permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>New <code>--declarationMap</code></h2>\n<p>Enabling <code>--declarationMap</code> alongside <code>--declaration</code> causes the compiler to emit <code>.d.ts.map</code> files alongside the output <code>.d.ts</code> files.\nLanguage Services can also now understand these map files, and uses them to map declaration-file based definition locations to their original source, when available.</p>\n<p>In other words, hitting go-to-definition on a declaration from a <code>.d.ts</code> file generated with <code>--declarationMap</code> will take you to the source file (<code>.ts</code>) location where that declaration was defined, and not to the <code>.d.ts</code>.</p>","headings":[{"value":"Support number and symbol named properties with keyof and mapped types","depth":2},{"value":"Example","depth":5},{"value":"Example","depth":5},{"value":"Recommendations","depth":4},{"value":"Generic type arguments in JSX elements","depth":2},{"value":"Example","depth":5},{"value":"Generic type arguments in generic tagged templates","depth":2},{"value":"Example","depth":5},{"value":"import types","depth":2},{"value":"Example","depth":5},{"value":"Relaxing declaration emit visiblity rules","depth":2},{"value":"Support for import.meta","depth":2},{"value":"Example","depth":5},{"value":"New --resolveJsonModule","depth":2},{"value":"Example","depth":5},{"value":"--pretty output by default","depth":2},{"value":"New --declarationMap","depth":2}],"frontmatter":{"permalink":"/docs/handbook/release-notes/typescript-2-9.html","title":"TypeScript 2.9"}}},"pageContext":{"slug":"/docs/handbook/release-notes/typescript-2-9.html","isOldHandbook":true}}}