{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/release-notes/typescript-2-8.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":"08cfd4d9-687a-5e0e-9bd3-2ba35a43ae67","excerpt":"Conditional Types TypeScript 2.8 introduces conditional types which add the ability to express non-uniform type mappings.\nA conditional type selects one of two…","html":"<h2 id=\"conditional-types\" style=\"position:relative;\"><a href=\"#conditional-types\" aria-label=\"conditional 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>Conditional Types</h2>\n<p>TypeScript 2.8 introduces <em>conditional types</em> which add the ability to express non-uniform type mappings.\nA conditional type selects one of two possible types based on a condition expressed as a type relationship test:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">T extends U ? X : Y</span></code></div></pre>\n<p>The type above means when <code>T</code> is assignable to <code>U</code> the type is <code>X</code>, otherwise the type is <code>Y</code>.</p>\n<p>A conditional type <code>T extends U ? X : Y</code> is either <em>resolved</em> to <code>X</code> or <code>Y</code>, or <em>deferred</em> because the condition depends on one or more type variables.\nWhether to resolve or defer is determined as follows:</p>\n<ul>\n<li>First, given types <code>T'</code> and <code>U'</code> that are instantiations of <code>T</code> and <code>U</code> where all occurrences of type parameters are replaced with <code>any</code>, if <code>T'</code> is not assignable to <code>U'</code>, the conditional type is resolved to <code>Y</code>. Intuitively, if the most permissive instantiation of <code>T</code> is not assignable to the most permissive instantiation of <code>U</code>, we know that no instantiation will be and we can just resolve to <code>Y</code>.</li>\n<li>Next, for each type variable introduced by an <code>infer</code> (more later) declaration within <code>U</code> collect a set of candidate types by inferring from <code>T</code> to <code>U</code> (using the same inference algorithm as type inference for generic functions). For a given <code>infer</code> type variable <code>V</code>, if any candidates were inferred from co-variant positions, the type inferred for <code>V</code> is a union of those candidates. Otherwise, if any candidates were inferred from contra-variant positions, the type inferred for <code>V</code> is an intersection of those candidates. Otherwise, the type inferred for <code>V</code> is <code>never</code>.</li>\n<li>Then, given a type <code>T''</code> that is an instantiation of <code>T</code> where all <code>infer</code> type variables are replaced with the types inferred in the previous step, if <code>T''</code> is <em>definitely assignable</em> to <code>U</code>, the conditional type is resolved to <code>X</code>. The definitely assignable relation is the same as the regular assignable relation, except that type variable constraints are not considered. Intuitively, when a type is definitely assignable to another type, we know that it will be assignable for <em>all instantiations</em> of those types.</li>\n<li>Otherwise, the condition depends on one or more type variables and the conditional type is deferred.</li>\n</ul>\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\">type</span><span style=\"color: #000000\"> TypeName&lt;T&gt; =</span>\n<span style=\"color: #000000\">    T extends string ? </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\"> :</span>\n<span style=\"color: #000000\">    T extends number ? </span><span style=\"color: #A31515\">\"number\"</span><span style=\"color: #000000\"> :</span>\n<span style=\"color: #000000\">    T extends boolean ? </span><span style=\"color: #A31515\">\"boolean\"</span><span style=\"color: #000000\"> :</span>\n<span style=\"color: #000000\">    T extends undefined ? </span><span style=\"color: #A31515\">\"undefined\"</span><span style=\"color: #000000\"> :</span>\n<span style=\"color: #000000\">    T extends Function ? </span><span style=\"color: #A31515\">\"function\"</span><span style=\"color: #000000\"> :</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #A31515\">\"object\"</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T0 = TypeName&lt;string&gt;;  </span><span style=\"color: #008000\">// \"string\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T1 = TypeName&lt;</span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\">&gt;;  </span><span style=\"color: #008000\">// \"string\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T2 = TypeName&lt;true&gt;;  </span><span style=\"color: #008000\">// \"boolean\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T3 = TypeName&lt;() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void&gt;;  </span><span style=\"color: #008000\">// \"function\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T4 = TypeName&lt;string[]&gt;;  </span><span style=\"color: #008000\">// \"object\"</span></code></div></pre>\n<h2 id=\"distributive-conditional-types\" style=\"position:relative;\"><a href=\"#distributive-conditional-types\" aria-label=\"distributive conditional 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>Distributive conditional types</h2>\n<p>Conditional types in which the checked type is a naked type parameter are called <em>distributive conditional types</em>.\nDistributive conditional types are automatically distributed over union types during instantiation.\nFor example, an instantiation of <code>T extends U ? X : Y</code> with the type argument <code>A | B | C</code> for <code>T</code> is resolved as <code>(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)</code>.</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\">type</span><span style=\"color: #000000\"> T10 = TypeName&lt;string | (() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void)&gt;;  </span><span style=\"color: #008000\">// \"string\" | \"function\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T12 = TypeName&lt;string | string[] | undefined&gt;;  </span><span style=\"color: #008000\">// \"string\" | \"object\" | \"undefined\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T11 = TypeName&lt;string[] | number[]&gt;;  </span><span style=\"color: #008000\">// \"object\"</span></code></div></pre>\n<p>In instantiations of a distributive conditional type <code>T extends U ? X : Y</code>, references to <code>T</code> within the conditional type are resolved to individual constituents of the union type (i.e. <code>T</code> refers to the individual constituents <em>after</em> the conditional type is distributed over the union type).\nFurthermore, references to <code>T</code> within <code>X</code> have an additional type parameter constraint <code>U</code> (i.e. <code>T</code> is considered assignable to <code>U</code> within <code>X</code>).</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\">type</span><span style=\"color: #000000\"> BoxedValue&lt;T&gt; = { value: T };</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> BoxedArray&lt;T&gt; = { array: T[] };</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Boxed&lt;T&gt; = T extends any[] ? BoxedArray&lt;T[number]&gt; : BoxedValue&lt;T&gt;;</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T20 = Boxed&lt;string&gt;;  </span><span style=\"color: #008000\">// BoxedValue&lt;string&gt;;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T21 = Boxed&lt;number[]&gt;;  </span><span style=\"color: #008000\">// BoxedArray&lt;number&gt;;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T22 = Boxed&lt;string | number[]&gt;;  </span><span style=\"color: #008000\">// BoxedValue&lt;string&gt; | BoxedArray&lt;number&gt;;</span></code></div></pre>\n<p>Notice that <code>T</code> has the additional constraint <code>any[]</code> within the true branch of <code>Boxed&#x3C;T></code> and it is therefore possible to refer to the element type of the array as <code>T[number]</code>. Also, notice how the conditional type is distributed over the union type in the last example.</p>\n<p>The distributive property of conditional types can conveniently be used to <em>filter</em> union types:</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\"> Diff&lt;T, U&gt; = T extends U ? never : T;  </span><span style=\"color: #008000\">// Remove types from T that are assignable to U</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Filter&lt;T, U&gt; = T extends U ? T : never;  </span><span style=\"color: #008000\">// Remove types from T that are not assignable to U</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T30 = Diff&lt;</span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"b\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"d\"</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"f\"</span><span style=\"color: #000000\">&gt;;  </span><span style=\"color: #008000\">// \"b\" | \"d\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T31 = Filter&lt;</span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"b\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"d\"</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"f\"</span><span style=\"color: #000000\">&gt;;  </span><span style=\"color: #008000\">// \"a\" | \"c\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T32 = Diff&lt;string | number | (() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void), Function&gt;;  </span><span style=\"color: #008000\">// string | number</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T33 = Filter&lt;string | number | (() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void), Function&gt;;  </span><span style=\"color: #008000\">// () =&gt; void</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> NonNullable&lt;T&gt; = Diff&lt;T, null | undefined&gt;;  </span><span style=\"color: #008000\">// Remove null and undefined from T</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T34 = NonNullable&lt;string | number | undefined&gt;;  </span><span style=\"color: #008000\">// string | number</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T35 = NonNullable&lt;string | string[] | null | undefined&gt;;  </span><span style=\"color: #008000\">// string | string[]</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f1&lt;T&gt;(x: T, y: NonNullable&lt;T&gt;) {</span>\n<span style=\"color: #000000\">    x = y;  </span><span style=\"color: #008000\">// Ok</span>\n<span style=\"color: #000000\">    y = x;  </span><span style=\"color: #008000\">// Error</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f2&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> string | undefined&gt;(x: T, y: NonNullable&lt;T&gt;) {</span>\n<span style=\"color: #000000\">    x = y;  </span><span style=\"color: #008000\">// Ok</span>\n<span style=\"color: #000000\">    y = x;  </span><span style=\"color: #008000\">// Error</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> s1: string = x;  </span><span style=\"color: #008000\">// Error</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> s2: string = y;  </span><span style=\"color: #008000\">// Ok</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Conditional types are particularly useful when combined with mapped types:</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\"> FunctionPropertyNames&lt;T&gt; = { [K </span><span style=\"color: #0000FF\">in</span><span style=\"color: #000000\"> keyof T]: T[K] extends Function ? K : never }[</span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> T];</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> FunctionProperties&lt;T&gt; = Pick&lt;T, FunctionPropertyNames&lt;T&gt;&gt;;</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> NonFunctionPropertyNames&lt;T&gt; = { [K </span><span style=\"color: #0000FF\">in</span><span style=\"color: #000000\"> keyof T]: T[K] extends Function ? never : K }[</span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> T];</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> NonFunctionProperties&lt;T&gt; = Pick&lt;T, NonFunctionPropertyNames&lt;T&gt;&gt;;</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Part {</span>\n<span style=\"color: #000000\">    id: number;</span>\n<span style=\"color: #000000\">    name: string;</span>\n<span style=\"color: #000000\">    subparts: Part[];</span>\n<span style=\"color: #000000\">    updatePart(newName: string): void;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T40 = FunctionPropertyNames&lt;Part&gt;;  </span><span style=\"color: #008000\">// \"updatePart\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T41 = NonFunctionPropertyNames&lt;Part&gt;;  </span><span style=\"color: #008000\">// \"id\" | \"name\" | \"subparts\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T42 = FunctionProperties&lt;Part&gt;;  </span><span style=\"color: #008000\">// { updatePart(newName: string): void }</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T43 = NonFunctionProperties&lt;Part&gt;;  </span><span style=\"color: #008000\">// { id: number, name: string, subparts: Part[] }</span></code></div></pre>\n<p>Similar to union and intersection types, conditional types are not permitted to reference themselves recursively.\nFor example the following is an error.</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\">type</span><span style=\"color: #000000\"> ElementType&lt;T&gt; = T extends any[] ? ElementType&lt;T[number]&gt; : T;  </span><span style=\"color: #008000\">// Error</span></code></div></pre>\n<h2 id=\"type-inference-in-conditional-types\" style=\"position:relative;\"><a href=\"#type-inference-in-conditional-types\" aria-label=\"type inference in conditional 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>Type inference in conditional types</h2>\n<p>Within the <code>extends</code> clause of a conditional type, it is now possible to have <code>infer</code> declarations that introduce a type variable to be inferred.\nSuch inferred type variables may be referenced in the true branch of the conditional type.\nIt is possible to have multiple <code>infer</code> locations for the same type variable.</p>\n<p>For example, the following extracts the return type of a function type:</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\"> ReturnType&lt;T&gt; = T extends (...args: any[]) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> infer R ? R : any;</span></code></div></pre>\n<p>Conditional types can be nested to form a sequence of pattern matches that are evaluated in order:</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\"> Unpacked&lt;T&gt; =</span>\n<span style=\"color: #000000\">    T extends (infer U)[] ? U :</span>\n<span style=\"color: #000000\">    T extends (...args: any[]) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> infer U ? U :</span>\n<span style=\"color: #000000\">    T extends Promise&lt;infer U&gt; ? U :</span>\n<span style=\"color: #000000\">    T;</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T0 = Unpacked&lt;string&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T1 = Unpacked&lt;string[]&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T2 = Unpacked&lt;() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> string&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T3 = Unpacked&lt;Promise&lt;string&gt;&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T4 = Unpacked&lt;Promise&lt;string&gt;[]&gt;;  </span><span style=\"color: #008000\">// Promise&lt;string&gt;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T5 = Unpacked&lt;Unpacked&lt;Promise&lt;string&gt;[]&gt;&gt;;  </span><span style=\"color: #008000\">// string</span></code></div></pre>\n<p>The following example demonstrates how multiple candidates for the same type variable in co-variant positions causes a union type to be inferred:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Foo&lt;T&gt; = T extends { a: infer U, b: infer U } ? U : never;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T10 = Foo&lt;{ a: string, b: string }&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T11 = Foo&lt;{ a: string, b: number }&gt;;  </span><span style=\"color: #008000\">// string | number</span></code></div></pre>\n<p>Likewise, multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred:</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\"> Bar&lt;T&gt; = T extends { a: (x: infer U) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void, b: (x: infer U) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void } ? U : never;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T20 = Bar&lt;{ a: (x: string) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void, b: (x: string) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void }&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T21 = Bar&lt;{ a: (x: string) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void, b: (x: number) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void }&gt;;  </span><span style=\"color: #008000\">// string & number</span></code></div></pre>\n<p>When inferring from a type with multiple call signatures (such as the type of an overloaded function), inferences are made from the <em>last</em> signature (which, presumably, is the most permissive catch-all case).\nIt is not possible to perform overload resolution based on a list of argument types.</p>\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\"> foo(x: string): number;</span>\n<span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> foo(x: number): string;</span>\n<span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> foo(x: string | number): string | number;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T30 = ReturnType&lt;</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> foo&gt;;  </span><span style=\"color: #008000\">// string | number</span></code></div></pre>\n<p>It is not possible to use <code>infer</code> declarations in constraint clauses for regular type parameters:</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\"> ReturnType&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> (...args: any[]) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> infer R&gt; = R;  </span><span style=\"color: #008000\">// Error, not supported</span></code></div></pre>\n<p>However, much the same effect can be obtained by erasing the type variables in the constraint and instead specifying a conditional type:</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\"> AnyFunction = (...args: any[]) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> any;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> ReturnType&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> AnyFunction&gt; = T extends (...args: any[]) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> infer R ? R : any;</span></code></div></pre>\n<h2 id=\"predefined-conditional-types\" style=\"position:relative;\"><a href=\"#predefined-conditional-types\" aria-label=\"predefined conditional 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>Predefined conditional types</h2>\n<p>TypeScript 2.8 adds several predefined conditional types to <code>lib.d.ts</code>:</p>\n<ul>\n<li><code>Exclude&#x3C;T, U></code> — Exclude from <code>T</code> those types that are assignable to <code>U</code>.</li>\n<li><code>Extract&#x3C;T, U></code> — Extract from <code>T</code> those types that are assignable to <code>U</code>.</li>\n<li><code>NonNullable&#x3C;T></code> — Exclude <code>null</code> and <code>undefined</code> from <code>T</code>.</li>\n<li><code>ReturnType&#x3C;T></code> — Obtain the return type of a function type.</li>\n<li><code>InstanceType&#x3C;T></code> — Obtain the instance type of a constructor function type.</li>\n</ul>\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<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T00 = Exclude&lt;</span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"b\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"d\"</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"f\"</span><span style=\"color: #000000\">&gt;;  </span><span style=\"color: #008000\">// \"b\" | \"d\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T01 = Extract&lt;</span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"b\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"d\"</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"a\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"c\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"f\"</span><span style=\"color: #000000\">&gt;;  </span><span style=\"color: #008000\">// \"a\" | \"c\"</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T02 = Exclude&lt;string | number | (() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void), Function&gt;;  </span><span style=\"color: #008000\">// string | number</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T03 = Extract&lt;string | number | (() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void), Function&gt;;  </span><span style=\"color: #008000\">// () =&gt; void</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T04 = NonNullable&lt;string | number | undefined&gt;;  </span><span style=\"color: #008000\">// string | number</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T05 = NonNullable&lt;(() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> string) | string[] | null | undefined&gt;;  </span><span style=\"color: #008000\">// (() =&gt; string) | string[]</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f1(s: string) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> { a: </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, b: s };</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">    x = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    y = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T10 = ReturnType&lt;() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> string&gt;;  </span><span style=\"color: #008000\">// string</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T11 = ReturnType&lt;(s: string) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> void&gt;;  </span><span style=\"color: #008000\">// void</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T12 = ReturnType&lt;(&lt;T&gt;() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> T)&gt;;  </span><span style=\"color: #008000\">// {}</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T13 = ReturnType&lt;(&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> U, U </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> number[]&gt;() </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> T)&gt;;  </span><span style=\"color: #008000\">// number[]</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T14 = ReturnType&lt;</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> f1&gt;;  </span><span style=\"color: #008000\">// { a: number, b: string }</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T15 = ReturnType&lt;any&gt;;  </span><span style=\"color: #008000\">// any</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T16 = ReturnType&lt;never&gt;;  </span><span style=\"color: #008000\">// any</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T17 = ReturnType&lt;string&gt;;  </span><span style=\"color: #008000\">// Error</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T18 = ReturnType&lt;Function&gt;;  </span><span style=\"color: #008000\">// Error</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T20 = InstanceType&lt;</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> C&gt;;  </span><span style=\"color: #008000\">// C</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T21 = InstanceType&lt;any&gt;;  </span><span style=\"color: #008000\">// any</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T22 = InstanceType&lt;never&gt;;  </span><span style=\"color: #008000\">// any</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T23 = InstanceType&lt;string&gt;;  </span><span style=\"color: #008000\">// Error</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T24 = InstanceType&lt;Function&gt;;  </span><span style=\"color: #008000\">// Error</span></code></div></pre>\n<blockquote>\n<p>Note: The <code>Exclude</code> type is a proper implementation of the <code>Diff</code> type suggested <a href=\"https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-307871458\">here</a>. We’ve used the name <code>Exclude</code> to avoid breaking existing code that defines a <code>Diff</code>, plus we feel that name better conveys the semantics of the type. We did not include the <code>Omit&#x3C;T, K></code> type because it is trivially written as <code>Pick&#x3C;T, Exclude&#x3C;keyof T, K>></code>.</p>\n</blockquote>\n<h2 id=\"improved-control-over-mapped-type-modifiers\" style=\"position:relative;\"><a href=\"#improved-control-over-mapped-type-modifiers\" aria-label=\"improved control over mapped type modifiers 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>Improved control over mapped type modifiers</h2>\n<p>Mapped types support adding a <code>readonly</code> or <code>?</code> modifier to a mapped property, but they did not provide support the ability to <em>remove</em> modifiers.\nThis matters in <a href=\"https://github.com/Microsoft/TypeScript/pull/12563\"><em>homomorphic mapped types</em></a> which by default preserve the modifiers of the underlying type.</p>\n<p>TypeScript 2.8 adds the ability for a mapped type to either add or remove a particular modifier.\nSpecifically, a <code>readonly</code> or <code>?</code> property modifier in a mapped type can now be prefixed with either <code>+</code> or <code>-</code> to indicate that the modifier should be added or removed.</p>\n<h4 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</h4>\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\"> MutableRequired&lt;T&gt; = { -readonly [P in keyof T]-?: T[P] };  </span><span style=\"color: #008000\">// Remove readonly and ?</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> ReadonlyPartial&lt;T&gt; = { +readonly [P in keyof T]+?: T[P] };  </span><span style=\"color: #008000\">// Add readonly and ?</span></code></div></pre>\n<p>A modifier with no <code>+</code> or <code>-</code> prefix is the same as a modifier with a <code>+</code> prefix. So, the <code>ReadonlyPartial&#x3C;T></code> type above corresponds to</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\"> ReadonlyPartial&lt;T&gt; = { </span><span style=\"color: #0000FF\">readonly</span><span style=\"color: #000000\"> [P </span><span style=\"color: #0000FF\">in</span><span style=\"color: #000000\"> keyof T]?: T[P] };  </span><span style=\"color: #008000\">// Add readonly and ?</span></code></div></pre>\n<p>Using this ability, <code>lib.d.ts</code> now has a new  <code>Required&#x3C;T></code> type.\nThis type strips <code>?</code> modifiers from all properties of <code>T</code>, thus making all properties required.</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: #0000FF\">type</span><span style=\"color: #000000\"> Required&lt;T&gt; = { [P in keyof T]-?: T[P] };</span></code></div></pre>\n<p>Note that in <code>--strictNullChecks</code> mode, when a homomorphic mapped type removes a <code>?</code> modifier from a property in the underlying type it also removes <code>undefined</code> from the type of that property:</p>\n<h5 id=\"example-7\" style=\"position:relative;\"><a href=\"#example-7\" aria-label=\"example 7 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\">type</span><span style=\"color: #000000\"> Foo = { a?: string };  </span><span style=\"color: #008000\">// Same as { a?: string | undefined }</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> Bar = Required&lt;Foo&gt;;  </span><span style=\"color: #008000\">// Same as { a: string }</span></code></div></pre>\n<h2 id=\"improved-keyof-with-intersection-types\" style=\"position:relative;\"><a href=\"#improved-keyof-with-intersection-types\" aria-label=\"improved keyof with intersection 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>Improved <code>keyof</code> with intersection types</h2>\n<p>With TypeScript 2.8 <code>keyof</code> applied to an intersection type is transformed to a union of <code>keyof</code> applied to each intersection constituent.\nIn other words, types of the form <code>keyof (A &#x26; B)</code> are transformed to be <code>keyof A | keyof B</code>.\nThis change should address inconsistencies with inference from <code>keyof</code> expressions.</p>\n<h5 id=\"example-8\" style=\"position:relative;\"><a href=\"#example-8\" aria-label=\"example 8 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\">type</span><span style=\"color: #000000\"> A = { a: string };</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> B = { b: string };</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T1 = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> (A & B);  </span><span style=\"color: #008000\">// \"a\" | \"b\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T2&lt;T&gt; = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> (T & B);  </span><span style=\"color: #008000\">// keyof T | \"b\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T3&lt;U&gt; = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> (A & U);  </span><span style=\"color: #008000\">// \"a\" | keyof U</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T4&lt;T, U&gt; = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> (T & U);  </span><span style=\"color: #008000\">// keyof T | keyof U</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T5 = T2&lt;A&gt;;  </span><span style=\"color: #008000\">// \"a\" | \"b\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T6 = T3&lt;B&gt;;  </span><span style=\"color: #008000\">// \"a\" | \"b\"</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> T7 = T4&lt;A, B&gt;;  </span><span style=\"color: #008000\">// \"a\" | \"b\"</span></code></div></pre>\n<h2 id=\"better-handling-for-namespace-patterns-in-js-files\" style=\"position:relative;\"><a href=\"#better-handling-for-namespace-patterns-in-js-files\" aria-label=\"better handling for namespace patterns in js files permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Better handling for namespace patterns in <code>.js</code> files</h2>\n<p>TypeScript 2.8 adds support for understanding more namespace patterns in <code>.js</code> files.\nEmpty object literals declarations on top level, just like functions and classes, are now recognized as as namespace declarations in JavaScript.</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> ns = {};     </span><span style=\"color: #008000\">// recognized as a declaration for a namespace `ns`</span>\n<span style=\"color: #000000\">ns.constant = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// recognized as a declaration for var `constant`</span></code></div></pre>\n<p>Assignments at the top-level should behave the same way; in other words, a <code>var</code> or <code>const</code> declaration is not required.</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #000000\">app = {}; </span><span style=\"color: #008000\">// does NOT need to be `var app = {}`</span>\n<span style=\"color: #000000\">app.C = </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">};</span>\n<span style=\"color: #000000\">app.f = </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">};</span>\n<span style=\"color: #000000\">app.prop = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">;</span></code></div></pre>\n<h2 id=\"iifes-as-namespace-declarations\" style=\"position:relative;\"><a href=\"#iifes-as-namespace-declarations\" aria-label=\"iifes as namespace declarations 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>IIFEs as namespace declarations</h2>\n<p>An IIFE returning a function, class or empty object literal, is also recognized as a namespace:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> C = (</span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> () {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> C(n) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.p = n;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> C;</span>\n<span style=\"color: #000000\">})();</span>\n<span style=\"color: #000000\">C.staticProperty = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">;</span></code></div></pre>\n<h2 id=\"defaulted-declarations\" style=\"position:relative;\"><a href=\"#defaulted-declarations\" aria-label=\"defaulted declarations 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>Defaulted declarations</h2>\n<p>“Defaulted declarations” allow initializers that reference the declared name in the left side of a logical or:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #000000\">my = window.my || {};</span>\n<span style=\"color: #000000\">my.app = my.app || {};</span></code></div></pre>\n<h2 id=\"prototype-assignment\" style=\"position:relative;\"><a href=\"#prototype-assignment\" aria-label=\"prototype assignment 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>Prototype assignment</h2>\n<p>You can assign an object literal directly to the prototype property. Individual prototype assignments still work too:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> C = </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> (p) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.p = p;</span>\n<span style=\"color: #000000\">};</span>\n<span style=\"color: #000000\">C.prototype = {</span>\n<span style=\"color: #000000\">  m() {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.p);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">};</span>\n<span style=\"color: #000000\">C.prototype.q = </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">(r) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.p === r;</span>\n<span style=\"color: #000000\">};</span></code></div></pre>\n<h2 id=\"nested-and-merged-declarations\" style=\"position:relative;\"><a href=\"#nested-and-merged-declarations\" aria-label=\"nested and merged declarations 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>Nested and merged declarations</h2>\n<p>Nesting works to any level now, and merges correctly across files. Previously neither was the case.</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> app = window.app || {};</span>\n<span style=\"color: #000000\">app.C = </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> { };</span></code></div></pre>\n<h2 id=\"per-file-jsx-factories\" style=\"position:relative;\"><a href=\"#per-file-jsx-factories\" aria-label=\"per file jsx factories 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>Per-file JSX factories</h2>\n<p>TypeScript 2.8 adds support for a per-file configurable JSX factory name using <code>@jsx dom</code> pragma.\nJSX factory can be configured for a compilation using <code>--jsxFactory</code> (default is <code>React.createElement</code>). With TypeScript 2.8 you can override this on a per-file-basis by adding a comment to the beginning of the file.</p>\n<h5 id=\"example-9\" style=\"position:relative;\"><a href=\"#example-9\" aria-label=\"example 9 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\">/** @jsx dom */</span>\n<span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> { dom } </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"./renderer\"</span>\n<span style=\"color: #000000\">&lt;h&gt;&lt;/h&gt;</span></code></div></pre>\n<p>Generates:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> renderer_1 = require(</span><span style=\"color: #A31515\">\"./renderer\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">renderer_1.dom(</span><span style=\"color: #A31515\">\"h\"</span><span style=\"color: #000000\">, </span><span style=\"color: #0000FF\">null</span><span style=\"color: #000000\">);</span></code></div></pre>\n<h2 id=\"locally-scoped-jsx-namespaces\" style=\"position:relative;\"><a href=\"#locally-scoped-jsx-namespaces\" aria-label=\"locally scoped jsx namespaces 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>Locally scoped JSX namespaces</h2>\n<p>JSX type checking is driven by definitions in a JSX namespace, for instance <code>JSX.Element</code> for the type of a JSX element, and <code>JSX.IntrinsicElements</code> for built-in elements.\nBefore TypeScript 2.8 the <code>JSX</code> namespace was expected to be in the global namespace, and thus only allowing one to be defined in a project.\nStarting with TypeScript 2.8 the <code>JSX</code> namespace will be looked under the <code>jsxNamespace</code> (e.g. <code>React</code>) allowing for multiple jsx factories in one compilation.\nFor backward compatibility the global <code>JSX</code> namespace is used as a fallback if none was defined on the factory function.\nCombined with the per-file <code>@jsx</code> pragma, each file can have a different JSX factory.</p>\n<h2 id=\"new---emitdeclarationonly\" style=\"position:relative;\"><a href=\"#new---emitdeclarationonly\" aria-label=\"new   emitdeclarationonly 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>--emitDeclarationOnly</code></h2>\n<p><code>--emitDeclarationOnly</code> allows for <em>only</em> generating declaration files; <code>.js</code>/<code>.jsx</code> output generation will be skipped with this flag. The flag is useful when the <code>.js</code> output generation is handled by a different transpiler like Babel.</p>","headings":[{"value":"Conditional Types","depth":2},{"value":"Example","depth":5},{"value":"Distributive conditional types","depth":2},{"value":"Example","depth":5},{"value":"Example","depth":5},{"value":"Example","depth":5},{"value":"Type inference in conditional types","depth":2},{"value":"Predefined conditional types","depth":2},{"value":"Example","depth":5},{"value":"Improved control over mapped type modifiers","depth":2},{"value":"Example","depth":4},{"value":"Example","depth":5},{"value":"Example","depth":5},{"value":"Improved keyof with intersection types","depth":2},{"value":"Example","depth":5},{"value":"Better handling for namespace patterns in .js files","depth":2},{"value":"IIFEs as namespace declarations","depth":2},{"value":"Defaulted declarations","depth":2},{"value":"Prototype assignment","depth":2},{"value":"Nested and merged declarations","depth":2},{"value":"Per-file JSX factories","depth":2},{"value":"Example","depth":5},{"value":"Locally scoped JSX namespaces","depth":2},{"value":"New --emitDeclarationOnly","depth":2}],"frontmatter":{"permalink":"/docs/handbook/release-notes/typescript-2-8.html","title":"TypeScript 2.8"}}},"pageContext":{"slug":"/docs/handbook/release-notes/typescript-2-8.html","isOldHandbook":true}}}