{"componentChunkName":"component---src-templates-documentation-tsx","path":"/docs/handbook/unions-and-intersections.html","result":{"data":{"allSitePage":{"nodes":[{"path":"/dev-404-page/"},{"path":"/docs/handbook/nightly-builds.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/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/basic-types.html"},{"path":"/docs/handbook/classes.html"},{"path":"/docs/handbook/enums.html"},{"path":"/docs/handbook/functions.html"},{"path":"/docs/handbook/generics.html"},{"path":"/docs/handbook/interfaces.html"},{"path":"/docs/handbook/literal-types.html"},{"path":"/docs/handbook/intro.html"},{"path":"/docs/handbook/unions-and-intersections.html"},{"path":"/docs/handbook/declaration-files/dts-from-js.html"},{"path":"/docs/handbook/intro-to-js-ts.html"},{"path":"/docs/handbook/jsdoc-supported-types.html"},{"path":"/docs/handbook/type-checking-javascript-files.html"},{"path":"/docs/handbook/compiler-options-in-msbuild.html"},{"path":"/docs/handbook/compiler-options.html"},{"path":"/docs/handbook/configuring-watch.html"},{"path":"/docs/handbook/integrating-with-build-tools.html"},{"path":"/docs/handbook/project-references.html"},{"path":"/docs/handbook/tsconfig-json.html"},{"path":"/docs/handbook/advanced-types.html"},{"path":"/docs/handbook/declaration-merging.html"},{"path":"/docs/handbook/decorators.html"},{"path":"/docs/handbook/iterators-and-generators.html"},{"path":"/docs/handbook/jsx.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/symbols.html"},{"path":"/docs/handbook/triple-slash-directives.html"},{"path":"/docs/handbook/type-compatibility.html"},{"path":"/docs/handbook/type-inference.html"},{"path":"/docs/handbook/utility-types.html"},{"path":"/docs/handbook/variable-declarations.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-1.html"},{"path":"/docs/handbook/release-notes/typescript-2-2.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/release-notes/typescript-3-9.html"},{"path":"/docs/handbook/asp-net-core.html"},{"path":"/docs/handbook/angular.html"},{"path":"/docs/handbook/babel-with-typescript.html"},{"path":"/docs/handbook/dom-manipulation.html"},{"path":"/docs/handbook/gulp.html"},{"path":"/docs/handbook/migrating-from-javascript.html"},{"path":"/docs/handbook/react.html"},{"path":"/docs/handbook/typescript-tooling-in-5-minutes.html"},{"path":"/vo/docs/handbook/basic-types.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":"/vo/tsconfig"},{"path":"/tsconfig"},{"path":"/en/tsconfig"},{"path":"/ja/tsconfig"},{"path":"/pt/tsconfig"},{"path":"/play"},{"path":"/en/play"},{"path":"/es/play"},{"path":"/fa/play"},{"path":"/pt/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/4-0/new-checks/class-constructor-code-flow.ts"},{"path":"/play/4-0/new-js-features/jsdoc-deprecated.ts"},{"path":"/play/4-0/new-js-features/logical-operators-and-assignment.ts"},{"path":"/play/4-0/new-js-features/nullish-coalescing.ts"},{"path":"/play/4-0/new-ts-features/named-tuples.ts"},{"path":"/play/4-0/new-ts-features/unknown-in-catch.ts"},{"path":"/play/4-0/new-ts-features/variadic-tuples.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/language/soundness.ts"},{"path":"/es/play/typescript/language/structural-typing.ts"},{"path":"/es/play/typescript/language/type-guards.ts"},{"path":"/es/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/es/play/typescript/meta-types/conditional-types.ts"},{"path":"/es/play/typescript/meta-types/discriminate-types.ts"},{"path":"/es/play/typescript/meta-types/indexed-types.ts"},{"path":"/es/play/typescript/meta-types/mapped-types.ts"},{"path":"/es/play/typescript/primitives/any.ts"},{"path":"/es/play/typescript/primitives/literals.ts"},{"path":"/es/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/es/play/typescript/primitives/unknown-and-never.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":"/fa/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/ja/play/3-7/fixits/big-number-literals.ts"},{"path":"/ja/play/3-7/syntax-and-messaging/nullish-coalescing.ts"},{"path":"/ja/play/3-7/syntax-and-messaging/optional-chaining.ts"},{"path":"/ja/play/3-8/breaking-changes/checking-unions-with-index-signatures.ts"},{"path":"/ja/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/ja/play/typescript/language-extensions/enums.ts"},{"path":"/ja/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/ja/play/3-7/fixits/infer-from-usage-changes.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/primitives/unknown-and-never.ts"},{"path":"/ja/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/ja/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/ja/play/3-7/fixits/const-to-let.ts"},{"path":"/ja/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/ja/play/typescript/type-primitives/nullable-types.ts"},{"path":"/ja/play/typescript/type-primitives/tuples.ts"},{"path":"/pt/play/3-7/fixits/big-number-literals.ts"},{"path":"/pt/play/3-7/fixits/const-to-let.ts"},{"path":"/pt/play/3-7/fixits/infer-from-usage-changes.ts"},{"path":"/pt/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/pt/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/pt/play/javascript/javascript-essentials/functions.ts"},{"path":"/pt/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/pt/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/pt/play/typescript/language-extensions/enums.ts"},{"path":"/pt/play/typescript/type-primitives/tuples.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/javascript-essentials/objects-and-arrays.ts"},{"path":"/zh/play/javascript/modern-javascript/async-await.ts"},{"path":"/zh/play/javascript/modern-javascript/immutability.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":"/community"},{"path":"/es/community"},{"path":"/ja/community"},{"path":"/pt/community"},{"path":"/vo/community"},{"path":"/zh/community"},{"path":"/download"},{"path":"/es/download"},{"path":"/ja/download"},{"path":"/pt/download"},{"path":"/vo/download"},{"path":"/zh/download"},{"path":"/empty"},{"path":"/es/empty"},{"path":"/ja/empty"},{"path":"/pt/empty"},{"path":"/vo/empty"},{"path":"/zh/empty"},{"path":"/"},{"path":"/es/"},{"path":"/ja/"},{"path":"/pt/"},{"path":"/vo/"},{"path":"/zh/"},{"path":"/tools"},{"path":"/es/tools"},{"path":"/ja/tools"},{"path":"/pt/tools"},{"path":"/vo/tools"},{"path":"/zh/tools"},{"path":"/why-create-typescript"},{"path":"/es/why-create-typescript"},{"path":"/ja/why-create-typescript"},{"path":"/pt/why-create-typescript"},{"path":"/vo/why-create-typescript"},{"path":"/zh/why-create-typescript"},{"path":"/docs/bootstrap"},{"path":"/es/docs/bootstrap"},{"path":"/ja/docs/bootstrap"},{"path":"/pt/docs/bootstrap"},{"path":"/vo/docs/bootstrap"},{"path":"/zh/docs/bootstrap"},{"path":"/docs/"},{"path":"/es/docs/"},{"path":"/ja/docs/"},{"path":"/pt/docs/"},{"path":"/vo/docs/"},{"path":"/zh/docs/"},{"path":"/docs/handbook/"},{"path":"/es/docs/handbook/"},{"path":"/ja/docs/handbook/"},{"path":"/pt/docs/handbook/"},{"path":"/vo/docs/handbook/"},{"path":"/zh/docs/handbook/"},{"path":"/branding/"},{"path":"/dev/bug-workbench/"},{"path":"/dev/playground-plugins/"},{"path":"/dev/sandbox/"},{"path":"/dev/twoslash/"},{"path":"/dev/typescript-vfs/"},{"path":"/upcoming/"}]},"markdownRemark":{"id":"9f23668e-6cad-5717-b58d-e5a393958844","excerpt":"So far, the handbook has covered types which are atomic objects.\nHowever, as you model more types you find yourself looking for tools which let you compose or…","html":"<p>So far, the handbook has covered types which are atomic objects.\nHowever, as you model more types you find yourself looking for tools which let you compose or combine existing types instead of creating them from scratch.</p>\n<p>Intersection and Union types are one of the ways in which you can compose types.</p>\n<h2 id=\"union-types\" style=\"position:relative;\"><a href=\"#union-types\" aria-label=\"union 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>Union Types</h2>\n<p>Occasionally, you’ll run into a library that expects a parameter to be either a <code>number</code> or a <code>string</code>.\nFor instance, take the following function:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * Takes a string and adds \"padding\" to the left.</span>\n<span style=\"color: #008000\"> * If &apos;padding&apos; is a string, then &apos;padding&apos; is appended to the left side.</span>\n<span style=\"color: #008000\"> * If &apos;padding&apos; is a number, then that number of spaces is added to the left side.</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function padLeft(value: string, padding: any): string'>padLeft</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) value: string'>value</data-lsp></span><span style=\"color: #000000\">: string, </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: any'>padding</data-lsp></span><span style=\"color: #000000\">: any) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: any'>padding</data-lsp></span><span style=\"color: #000000\"> === </span><span style=\"color: #A31515\">\"number\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <data-lsp lsp='var Array: ArrayConstructor&amp;#13;(arrayLength?: number | undefined) => any[] (+2 overloads)'>Array</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: number'>padding</data-lsp></span><span style=\"color: #000000\"> + </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">).<data-lsp lsp='(method) Array&amp;lt;any>.join(separator?: string | undefined): string'>join</data-lsp>(</span><span style=\"color: #A31515\">\" \"</span><span style=\"color: #000000\">) + </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) value: string'>value</data-lsp></span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: any'>padding</data-lsp></span><span style=\"color: #000000\"> === </span><span style=\"color: #A31515\">\"string\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: string'>padding</data-lsp></span><span style=\"color: #000000\"> + </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) value: string'>value</data-lsp></span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> <data-lsp lsp='var Error: ErrorConstructor&amp;#13;new (message?: string | undefined) => Error'>Error</data-lsp>(</span><span style=\"color: #A31515\">`Expected string or number, got &apos;</span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: any'>padding</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">&apos;.`</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\"><data-lsp lsp='function padLeft(value: string, padding: any): string'>padLeft</data-lsp>(</span><span style=\"color: #A31515\">\"Hello world\"</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">4</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// returns \"    Hello world\"</span></code><a href='https://www.typescriptlang.org/play/#code/PQKhCgAIUgVBDA1gUwM6XpVAXATgSwDsBzDQgEw3PPQCIAHeao42ybAe3YAtlIAbZADNsAOigwAkkMgByRsxKzI+dJhwESAGh7JCcheRbLVGevT3lklTroHDsWfFfHRI0g0yNKVayIQBXAFsAI2RcHWxefSj4R0DQ8MgOGVRGAGM0XyorGy4ovkERJxcJYHAhAMJ07HwOfQUAGQcACgA3eH4A5AAuLDwWHUMWPvhCAE8ASkgAbygVGRbscYsUyGGSSABeHchaBLDcWmm5yDPIXGRsANx9AEFcXHhxlo3SAGpIAEZJ0QArDhEFpsY6QT4dLrIADc8wAvvN8ItlqsZG9trtaBoWKDTudLtdbusvCwwZAId0YWd4WcorgOAB3fzIRkAUUeHFwLQABiyAB4WGrWfqaUgc-zBQ46YgcRyyAAkMzesNkoi5kxh8PATVatAAEsh+PwuPSOfxyLQdAAWdWQYDAC5XG6EOjnSD6w3G03moA'>Try</a></div></pre>\n<p>The problem with <code>padLeft</code> in the above example is that its <code>padding</code> parameter is typed as <code>any</code>.\nThat means that we can call it with an argument that’s neither a <code>number</code> nor a <code>string</code>, but TypeScript will be okay with it.</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// passes at compile time, fails at runtime.</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='let indentedString: string'>indentedString</data-lsp> </span><span style=\"color: #000000\">= <data-lsp lsp='function padLeft(value: string, padding: any): string'>padLeft</data-lsp>(</span><span style=\"color: #A31515\">\"Hello world\"</span><span style=\"color: #000000\">, </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">);</span></code><a href='https://www.typescriptlang.org/play/#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwAcpgAZERDACgDcoJkQAueAZwxi1QHMAaQ44Jy7MoqAJ4BKZmw7cA3ACgA9EvgBaDWGQYNa5aqIsWIFvCgZ4YHAFsCWCAmzWQfRFHunz8GGicgAdAoOFpygqBggwADK7ELwALz8pORUAEQAEiAQEDjwAO44MBDAqXzsDBJyQA'>Try</a></div></pre>\n<p>In traditional object-oriented code, we might abstract over the two types by creating a hierarchy of types.\nWhile this is much more explicit, it’s also a little bit overkill.\nOne of the nice things about the original version of <code>padLeft</code> was that we were able to just pass in primitives.\nThat meant that usage was simple and concise.\nThis new approach also wouldn’t help if we were just trying to use a function that already exists elsewhere.</p>\n<p>Instead of <code>any</code>, we can use a <em>union type</em> for the <code>padding</code> parameter:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * Takes a string and adds \"padding\" to the left.</span>\n<span style=\"color: #008000\"> * If &apos;padding&apos; is a string, then &apos;padding&apos; is appended to the left side.</span>\n<span style=\"color: #008000\"> * If &apos;padding&apos; is a number, then that number of spaces is added to the left side.</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function padLeft(value: string, padding: string | number): void'>padLeft</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) value: string'>value</data-lsp></span><span style=\"color: #000000\">: string, </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) padding: string | number'>padding</data-lsp></span><span style=\"color: #000000\">: string | number) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='let indentedString: void'>indentedString</data-lsp> </span><span style=\"color: #000000\">= <data-lsp lsp='function padLeft(value: string, padding: string | number): void'>padLeft</data-lsp>(</span><span style=\"color: #A31515\">\"Hello world\"</span><span style=\"color: #000000\">, </span><span style=\"color: #0000FF\"><data-err>true</data-err></span><span style=\"color: #000000\">);</span>\n<span class=\"error\"><span>Argument of type 'boolean' is not assignable to parameter of type 'string | number'.</span><span class=\"code\">2345</span></span><span class=\"error-behind\">Argument of type 'boolean' is not assignable to parameter of type 'string | number'.</span></code><a href='https://www.typescriptlang.org/play/#code/PTAEAEFMCdoe2gZwFygEwGYAsBWAUMAFSF6iGgAqAhgNaSKhWiIAu0AlgHYDmjnAJo378GAIgAOVYV26jQLOPIAWkUABtIAMxYA6UuQCSm0AHJJ0nidDsGTVhx4AaZZE6nz-GVZuNx41-yQggou6loszOyBemSgRu5SnpbWtqCcAK4AtgBGMM4sKm4FVBEZOTCgcMaIkgDG9ClCgcGKBaoa2pHR+sB4mumctSzscG7mADLhABQAblRq6ZCo9jLOHjLLbDKgAD5pWbnQAJSgAN6koCCgOjd4AL54eBoRXIGcLEEAyls8oAC8oAm01EAAlIGo1IoAO4INT8UT5aCLI4AbiAA'>Try</a></div></pre>\n<p>A union type describes a value that can be one of several types.\nWe use the vertical bar (<code>|</code>) to separate each type, so <code>number | string | boolean</code> is the type of a value that can be a <code>number</code>, a <code>string</code>, or a <code>boolean</code>.</p>\n<h2 id=\"unions-with-common-fields\" style=\"position:relative;\"><a href=\"#unions-with-common-fields\" aria-label=\"unions with common fields 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>Unions with Common Fields</h2>\n<p>If we have a value that is a union type, we can only access members that are common to all types in the union.</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <data-lsp lsp='interface Bird'>Bird</data-lsp> {</span>\n<span style=\"color: #000000\">  <data-lsp lsp='(method) Bird.fly(): void'>fly</data-lsp>(): void;</span>\n<span style=\"color: #000000\">  <data-lsp lsp='(method) Bird.layEggs(): void'>layEggs</data-lsp>(): void;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <data-lsp lsp='interface Fish'>Fish</data-lsp> {</span>\n<span style=\"color: #000000\">  <data-lsp lsp='(method) Fish.swim(): void'>swim</data-lsp>(): void;</span>\n<span style=\"color: #000000\">  <data-lsp lsp='(method) Fish.layEggs(): void'>layEggs</data-lsp>(): void;</span>\n<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\"> <data-lsp lsp='function getSmallPet(): Fish | Bird'>getSmallPet</data-lsp>(): <data-lsp lsp='interface Fish'>Fish</data-lsp> | <data-lsp lsp='interface Bird'>Bird</data-lsp>;</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='let pet: Bird | Fish'>pet</data-lsp> </span><span style=\"color: #000000\">= <data-lsp lsp='function getSmallPet(): Fish | Bird'>getSmallPet</data-lsp>();</span>\n<span style=\"color: #1A1A1A\"><data-lsp lsp='let pet: Bird | Fish'>pet</data-lsp></span><span style=\"color: #000000\">.<data-lsp lsp='(method) layEggs(): void'>layEggs</data-lsp>();</span>\n\n<span style=\"color: #008000\">// Only available in one of the two possible types</span>\n<span style=\"color: #1A1A1A\"><data-lsp lsp='let pet: Bird | Fish'>pet</data-lsp></span><span style=\"color: #000000\"><data-err>.<data-lsp lsp='any'>swim</data-lsp>();</data-err></span>\n<span class=\"error\"><span>Property 'swim' does not exist on type 'Bird | Fish'.\n  Property 'swim' does not exist on type 'Bird'.</span><span class=\"code\">2339</span></span><span class=\"error-behind\">Property 'swim' does not exist on type 'Bird | Fish'.\n  Property 'swim' does not exist on type 'Bird'.</span></code><a href='https://www.typescriptlang.org/play/#code/PTAEAEFMCdoe2gZwFygEwGYME4BQuBLAOwBcYAzAQwGNJQAhA6AE1AG9dRRyAbATwAUASlQA3OAWYBuTqB6U+AUQDmyxMLETpuAL75iZaFVqgAYgUQALdrMQB3AgFsNocZJld5S1epGutMnq4zJDU8tB05ACuRNQkBHBEoMqQJADKjpQ8PAAKqS7mVqAAPgxM2rg8qaAADtUAvMmpGVm5+UIydSQAdF4qasIyuCCgAPJE-KCUopQE8gBGVaDEoIl0cOSgJJZ0JHZwtXCIiASLu3x1iLhd3fZOg0A'>Try</a></div></pre>\n<p>Union types can be a bit tricky here, but it just takes a bit of intuition to get used to.\nIf a value has the type <code>A | B</code>, we only know for <em>certain</em> that it has members that both <code>A</code> <em>and</em> <code>B</code> have.\nIn this example, <code>Bird</code> has a member named <code>fly</code>.\nWe can’t be sure whether a variable typed as <code>Bird | Fish</code> has a <code>fly</code> method.\nIf the variable is really a <code>Fish</code> at runtime, then calling <code>pet.fly()</code> will fail.</p>\n<h2 id=\"discriminating-unions\" style=\"position:relative;\"><a href=\"#discriminating-unions\" aria-label=\"discriminating unions 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>Discriminating Unions</h2>\n<p>A common technique for working with unions is to have a single field which uses literal types which you can use to let TypeScript narrow down the possible current type. For example, we’re going to create a union of three types which have a single shared field.</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\"> NetworkLoadingState = {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\">state</span><span style=\"color: #000000\">: </span><span style=\"color: #A31515\">\"loading\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> NetworkFailedState = {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\">state</span><span style=\"color: #000000\">: </span><span style=\"color: #A31515\">\"failed\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\">code</span><span style=\"color: #000000\">: number;</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> NetworkSuccessState = {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\">state</span><span style=\"color: #000000\">: </span><span style=\"color: #A31515\">\"success\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\">response</span><span style=\"color: #000000\">: {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #1A1A1A\">title</span><span style=\"color: #000000\">: string;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #1A1A1A\">duration</span><span style=\"color: #000000\">: number;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #1A1A1A\">summary</span><span style=\"color: #000000\">: string;</span>\n<span style=\"color: #000000\">  };</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #008000\">// Create a type which represents only one of the above types</span>\n<span style=\"color: #008000\">// but you aren't sure which it is yet.</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> NetworkState =</span>\n<span style=\"color: #000000\">  | NetworkLoadingState</span>\n<span style=\"color: #000000\">  | NetworkFailedState</span>\n<span style=\"color: #000000\">  | NetworkSuccessState;</span></code></div></pre>\n<style type=\"text/css\">\n.markdown table.tg  {\n  border-collapse:collapse;\n  width: 100%;\n  text-align: center;\n  display: table;\n}\n\n.tg th {\n  border-bottom: 1px solid black;\n  padding: 8px;\n  padding-bottom: 0;\n}\n\n.tg tbody, .tg tr {\n  width: 100%;\n}\n\n.tg .highlight {\n  background-color: #F3F3F3;\n}\n\n@media (prefers-color-scheme: dark) {\n  .tg .highlight {\n    background-color: #424242;\n  }\n}\n\n</style>\n<p>All of the above types have a field named <code>state</code>, and then they also have their own fields:</p>\n<table class='tg' width=\"100%\">\n  <tbody>\n    <tr>\n      <th><code>NetworkLoadingState</code></th>\n      <th><code>NetworkFailedState</code></th>\n      <th><code>NetworkSuccessState</code></th>\n    </tr>\n    <tr class='highlight'>\n      <td>state</td>\n      <td>state</td>\n      <td>state</td>\n    </tr>\n    <tr>\n      <td></td>\n      <td>code</td>\n      <td>response</td>\n    </tr>\n    </tbody>\n</table>\n<p>Given the <code>state</code> field is common in every type inside <code>NetworkState</code> - it is safe for your code to access without an existence check.</p>\n<p>With <code>state</code> as a literal type, you can compare the value of <code>state</code> to the equivalent string and TypeScript will know which type is currently being used.</p>\n<table class='tg' width=\"100%\">\n  <tbody>\n    <tr>\n      <th><code>NetworkLoadingState</code></th>\n      <th><code>NetworkFailedState</code></th>\n      <th><code>NetworkSuccessState</code></th>\n    </tr>\n    <tr>\n      <td><code>\"loading\"</code></td>\n      <td><code>\"failed\"</code></td>\n      <td><code>\"success\"</code></td>\n    </tr>\n    </tbody>\n</table>\n<p>In this case, you can use a <code>switch</code> statement to narrow down which type is represented at runtime:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> <data-lsp lsp='type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState'>NetworkState</data-lsp> =</span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkLoadingState = {&amp;#13;    state: &amp;quot;loading&amp;quot;;&amp;#13;}'>NetworkLoadingState</data-lsp></span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkFailedState = {&amp;#13;    state: &amp;quot;failed&amp;quot;;&amp;#13;    code: number;&amp;#13;}'>NetworkFailedState</data-lsp></span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkSuccessState = {&amp;#13;    state: &amp;quot;success&amp;quot;;&amp;#13;    response: {&amp;#13;        title: string;&amp;#13;        duration: number;&amp;#13;        summary: string;&amp;#13;    };&amp;#13;}'>NetworkSuccessState</data-lsp>;</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function networkStatus(state: NetworkState): string'>networkStatus</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) state: NetworkState'>state</data-lsp></span><span style=\"color: #000000\">: <data-lsp lsp='type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState'>NetworkState</data-lsp>): string {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Right now TypeScript does not know which of the three</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// potential types state could be.</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Trying to access a property which isn&apos;t shared</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// across all types will raise an error</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) state: NetworkState'>state</data-lsp></span><span style=\"color: #000000\"><data-err>.<data-lsp lsp='any'>code</data-lsp>;</data-err></span>\n<span class=\"error\"><span>Property 'code' does not exist on type 'NetworkState'.\n  Property 'code' does not exist on type 'NetworkLoadingState'.</span><span class=\"code\">2339</span></span><span class=\"error-behind\">Property 'code' does not exist on type 'NetworkState'.\n  Property 'code' does not exist on type 'NetworkLoadingState'.</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// By switching on state, TypeScript can narrow the union</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// down in code flow analysis</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">switch</span><span style=\"color: #000000\"> (</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) state: NetworkState'>state</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) state: &amp;quot;loading&amp;quot; | &amp;quot;failed&amp;quot; | &amp;quot;success&amp;quot;'>state</data-lsp></span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"Downloading...\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"failed\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #008000\">// The type must be NetworkFailedState here,</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #008000\">// so accessing the `code` field is safe</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">`Error </span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) state: NetworkFailedState'>state</data-lsp></span><span style=\"color: #A31515\">.<data-lsp lsp='(property) code: number'>code</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\"> downloading`</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"success\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">`Downloaded </span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) state: NetworkSuccessState'>state</data-lsp></span><span style=\"color: #A31515\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) response: {&amp;#13;    title: string;&amp;#13;    duration: number;&amp;#13;    summary: string;&amp;#13;}'>response</data-lsp></span><span style=\"color: #A31515\">.<data-lsp lsp='(property) title: string'>title</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\"> - </span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) state: NetworkSuccessState'>state</data-lsp></span><span style=\"color: #A31515\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) response: {&amp;#13;    title: string;&amp;#13;    duration: number;&amp;#13;    summary: string;&amp;#13;}'>response</data-lsp></span><span style=\"color: #A31515\">.<data-lsp lsp='(property) summary: string'>summary</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code><a href='https://www.typescriptlang.org/play/#code/PTAEAEFMCdoe2gZwFygEwGYME4BQAXATwAdJQA5SfAdwQGsAZOAQwBMBLAOwHMBlfZvjIBeUAG9coUIgFDUAIgA2LDj3kBuXAF9NBEmUo16AMWbtFkVv0Ejxk6bMgKAZmYusN9gMZxWT0JwArgC2AEYwmjq4eqQUVLTQdLyBXl6QiIjWQqCiElIyNgqIKWkZnlLQ6cRwnIj+eVKg+Oz4Fqgy0Fzcmo2grIHQguw1qEFhEfb5IcHM0ITt+J08PaBRUSCgALTbXoH425sxBvH0WSL2AD5xRolMbF1nl9cJdKbmlo9SV4YvyanpmUcumcgU4XmaNQCJ0SWUCiAAFAU5M9To4AJQLJbcOxSDYAJXY3AAFvgAnBqKAACr6XheTrEUmsODpMmkuiccmgahE9heImgODOJpEsj4ImVSD2DbVIScZrMRRNfSIBw2UA+QKKVigcIAOmiuLAlLmXSacFAzH+GQtoGI8FI0CIXJ5fNA7EQnAA5KTEETZpYpWBLfBrQrFURSCrqOZFYN3WRmJxQDB4NB7EjILqfH5dIbQAAhQjSaP4PmmyEZgA0VJpdPYDPViYCs3gFLFZFBw04gb65KTXHVvjIzmUFMTCsIiHd6ZLrsRjl1GbROMaXmYdVAShUXXkyEmjUq+AGSfkABE+8p7jxdTfyqv12R5K53h497085SRUrYsE4aTwiiiRvO4ZygCKlSVvueaIOalqlFOPDCmQAAG2aQMhoDOOwkBam6KqIMwziSu+oCHseoDIQAorACCgAAJGIGZZkOWi9tQnCXqo3DISsUhrhu8jFFaiC7lBpFUORyHnuxnGWPRjELpUiDVLUmbNK0kCsZs8lMUpKl1Iu0yzIQWg8fYWjaEAA'>Try</a></div></pre>\n<h2 id=\"union-exhaustiveness-checking\" style=\"position:relative;\"><a href=\"#union-exhaustiveness-checking\" aria-label=\"union exhaustiveness checking 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>Union Exhaustiveness checking</h2>\n<p>We would like the compiler to tell us when we don’t cover all variants of the discriminated union.\nFor example, if we add <code>NetworkFromCachedState</code> to <code>NetworkState</code>, we need to update <code>logger</code> as well:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> <data-lsp lsp='type NetworkFromCachedState = {&amp;#13;    state: &amp;quot;from_cache&amp;quot;;&amp;#13;    id: string;&amp;#13;    response: NetworkSuccessState[&amp;quot;response&amp;quot;];&amp;#13;}'>NetworkFromCachedState</data-lsp> = {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) state: &amp;quot;from_cache&amp;quot;'>state</data-lsp></span><span style=\"color: #000000\">: </span><span style=\"color: #A31515\">\"from_cache\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) id: string'>id</data-lsp></span><span style=\"color: #000000\">: string</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) response: {&amp;#13;    title: string;&amp;#13;    duration: number;&amp;#13;    summary: string;&amp;#13;}'>response</data-lsp></span><span style=\"color: #000000\">: <data-lsp lsp='type NetworkSuccessState = {&amp;#13;    state: &amp;quot;success&amp;quot;;&amp;#13;    response: {&amp;#13;        title: string;&amp;#13;        duration: number;&amp;#13;        summary: string;&amp;#13;    };&amp;#13;}'>NetworkSuccessState</data-lsp>[</span><span style=\"color: #A31515\">\"response\"</span><span style=\"color: #000000\">]</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> <data-lsp lsp='type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState | NetworkFromCachedState'>NetworkState</data-lsp> =</span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkLoadingState = {&amp;#13;    state: &amp;quot;loading&amp;quot;;&amp;#13;}'>NetworkLoadingState</data-lsp></span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkFailedState = {&amp;#13;    state: &amp;quot;failed&amp;quot;;&amp;#13;    code: number;&amp;#13;}'>NetworkFailedState</data-lsp></span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkSuccessState = {&amp;#13;    state: &amp;quot;success&amp;quot;;&amp;#13;    response: {&amp;#13;        title: string;&amp;#13;        duration: number;&amp;#13;        summary: string;&amp;#13;    };&amp;#13;}'>NetworkSuccessState</data-lsp></span>\n<span style=\"color: #000000\">  | <data-lsp lsp='type NetworkFromCachedState = {&amp;#13;    state: &amp;quot;from_cache&amp;quot;;&amp;#13;    id: string;&amp;#13;    response: NetworkSuccessState[&amp;quot;response&amp;quot;];&amp;#13;}'>NetworkFromCachedState</data-lsp>;</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function logger(s: NetworkState): string | undefined'>logger</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkState'>s</data-lsp></span><span style=\"color: #000000\">: <data-lsp lsp='type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState | NetworkFromCachedState'>NetworkState</data-lsp>) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">switch</span><span style=\"color: #000000\"> (</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkState'>s</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) state: &amp;quot;loading&amp;quot; | &amp;quot;failed&amp;quot; | &amp;quot;success&amp;quot; | &amp;quot;from_cache&amp;quot;'>state</data-lsp></span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading request\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"failed\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">`failed with code </span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkFailedState'>s</data-lsp></span><span style=\"color: #A31515\">.<data-lsp lsp='(property) code: number'>code</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"success\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"got response\"</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code><a href='https://www.typescriptlang.org/play/#code/PTAEAEFMCdoe2gZwFygEwGYBsWBQAXATwAdJQA5SfAdwQGsAZOAQwBMBLAOwHMBlfZvjIBeUAG9QiAUNQAiADYsOPWaAC+AbgIkylGvQBizdvMit+gkeMnTIcgGbHTrWRtABjOKzuhOAVwBbACMYdS0iUgoqWmg6Xj93d0hERAshUFExXFAbSzlEBKSU12zQaGTiOE5EHyycnPx2fFNUKWgubi160FY-aEF2KtR-YJgu+oKAgOZoQlb8dp5xzVwVkFAAWi33P3wtje1IvRi6A3gAgGFmdwALMzSrOtyZUFl7c4B9d2u7kpz2VjzRbcUrlRCVao+Y70eKJZKpWwAbVkYIhNVkAF1VrhDrpojDbBlSgAfKL6WJMNgdB4ksknIwme62WnQ2KwooIyws-GxM5wS4-JmWLS4ex+TjuRpVUCKbjcGAAChQdIJlgAlOJSohqE1bqAlQA6KTqzXdb41V6KKkqZClbrlfB9TiWpQdMqQACOfmS+D+9XNZDeTjMslt3RyDqdoAABo5GaxQDr8DcPF4yAASMSIA2ebxqaPjHIB14FOHFMPhyPQZ2ybhwfDu8FVdGlNSrIA'>Try</a></div></pre>\n<p>There are two ways to do this.\nThe first is to turn on <code>--strictNullChecks</code> and specify a return type:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function logger(s: NetworkState): string'>logger</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkState'>s</data-lsp></span><span style=\"color: #000000\"><data-err>: <data-lsp lsp='type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState | NetworkFromCachedState'>NetworkState</data-lsp>): string {</data-err></span>\n<span class=\"error\"><span>Function lacks ending return statement and return type does not include 'undefined'.</span><span class=\"code\">2366</span></span><span class=\"error-behind\">Function lacks ending return statement and return type does not include 'undefined'.</span><span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">switch</span><span style=\"color: #000000\"> (</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkState'>s</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) state: &amp;quot;loading&amp;quot; | &amp;quot;failed&amp;quot; | &amp;quot;success&amp;quot; | &amp;quot;from_cache&amp;quot;'>state</data-lsp></span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading request\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"failed\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">`failed with code </span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkFailedState'>s</data-lsp></span><span style=\"color: #A31515\">.<data-lsp lsp='(property) code: number'>code</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"success\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"got response\"</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code><a href='https://www.typescriptlang.org/play/#code/PTAEAEFMCdoe2gZwFygEwGYBsWBQAXATwAdJQA5SfAdwQGsAZOAQwBMBLAOwHMBlfZvjIBeUAG9QiAUNQAiADYsOPWaAC+AbgIkylGvQBizdvMit+gkeMnTIcgGbHTrWRtABjOKzuhOAVwBbACMYdS0iUgoqWmg6Xj93d0hERAshUFEJKUs5RASklNVNbUi9GLoDeACAYWZ3AAszNKss2wcqgH13OsbXdVwS3Wj6ZozcUFAAHyj9WKY2Lj5bcamZ8qMTJuWJ6bKR-OTU7dW92Mq4Gp6tyy1cEFAAWif3P3wnh9x7P053fHY4TigRTcbgwAAUKDWI1sAEpUFJoItxCtENR2PgGqAIQA6bJCGHIiYTbqIMgKJSLWTIFZE0DQKh+aCA8kLHh0yAARz8yXwrhpHmYpNAskcmxc1NpE3p+EZgIABqLnKA0fh6h4vGQACRiRDYzzeNRyrS0klkvKJQ5U-lShlM4XcOD4dmIYgA0myFZqXBqIA'>Try</a></div></pre>\n<p>Because the <code>switch</code> is no longer exhaustive, TypeScript is aware that the function could sometimes return <code>undefined</code>.\nIf you have an explicit return type <code>string</code>, then you will get an error that the return type is actually <code>string | undefined</code>.\nHowever, this method is quite subtle and, besides, <a href=\"/tsconfig#strictNullChecks\"><code>--strictNullChecks</code></a> does not always work with old code.</p>\n<p>The second method uses the <code>never</code> type that the compiler uses to check for exhaustiveness:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function assertNever(x: never): never'>assertNever</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) x: never'>x</data-lsp></span><span style=\"color: #000000\">: never): never {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> <data-lsp lsp='var Error: ErrorConstructor&amp;#13;new (message?: string | undefined) => Error'>Error</data-lsp>(</span><span style=\"color: #A31515\">\"Unexpected object: \"</span><span style=\"color: #000000\"> + </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) x: never'>x</data-lsp></span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <data-lsp lsp='function logger(s: NetworkState): string'>logger</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkState'>s</data-lsp></span><span style=\"color: #000000\">: <data-lsp lsp='type NetworkState = NetworkLoadingState | NetworkFailedState | NetworkSuccessState | NetworkFromCachedState'>NetworkState</data-lsp>): string {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">switch</span><span style=\"color: #000000\"> (</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkState'>s</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) state: &amp;quot;loading&amp;quot; | &amp;quot;failed&amp;quot; | &amp;quot;success&amp;quot; | &amp;quot;from_cache&amp;quot;'>state</data-lsp></span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"loading request\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"failed\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">`failed with code </span><span style=\"color: #0000FF\">${</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) s: NetworkFailedState'>s</data-lsp></span><span style=\"color: #A31515\">.<data-lsp lsp='(property) code: number'>code</data-lsp></span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">`</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">case</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"success\"</span><span style=\"color: #000000\">:</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"got response\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">default</span><span style=\"color: #000000\">: </span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <data-lsp lsp='function assertNever(x: never): never'>assertNever</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-err><data-lsp lsp='(parameter) s: NetworkFromCachedState'>s</data-lsp></data-err></span><span style=\"color: #000000\">)</span>\n<span class=\"error\"><span>Argument of type 'NetworkFromCachedState' is not assignable to parameter of type 'never'.</span><span class=\"code\">2345</span></span><span class=\"error-behind\">Argument of type 'NetworkFromCachedState' is not assignable to parameter of type 'never'.</span><span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code><a href='https://www.typescriptlang.org/play/#code/PTAEAEFMCdoe2gZwFygEwGYAsBWAUAC4CeADpKAHKQEDuCA1gDJwCGAJgJYB2A5gMoEWBcgF5QAb1CJBw1ACIANq0685oAL4BuQqXJVaDAGIsOCyGwFDREqTMjyAZibNs5m0AGM4be6C4BXAFsAIxgNbWIySmo6aHo+fw8PSERES2FQMUlpK3lEROTUtS0dKP1Y+kN4QIBhFg8AC3N062y7R2qAfQ96prcNPFK9GIYWzLxQUAAfaIM45nZufjsJ6dmK41NmlcmZ8tGClLSdtf24qrha3u2rbRBQAFonj38CJ4e8B38uDwIOOC4oBYqRgBCoADcYAAKAAeqC4kEh0AAlPDEWFxKsCA14DQ-JA8QBRWAIKFyACqCJhZF+5lAcGCACtIL95KAANSgGHI7TqQZfH5-AGgJQ8HjQlDrUZ2VG2aBLCSrRA0DgERqgKGIAB0OWEyMVk0mPUQ5EUyiWcmQq0NoGg1H80EBZsWvFtkAAjv4UgQ3NbPMDTU4tq4rTbJnaCA7AQADIMuUAq7GebzkAAk4m1Xh86mj2htxtN+SSR0tfvD9sdoDkPDgBDdiBIAJNvptPic-gUBFQZbdkcrwJN0DB6OgmuRqz56iAA'>Try</a></div></pre>\n<p>Here, <code>assertNever</code> checks that <code>s</code> is of type <code>never</code> — the type that’s left after all other cases have been removed.\nIf you forget a case, then <code>s</code> will have a real type and you will get a type error.\nThis method requires you to define an extra function, but it’s much more obvious when you forget it because the error message includes the missing type name.</p>\n<h2 id=\"intersection-types\" style=\"position:relative;\"><a href=\"#intersection-types\" aria-label=\"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>Intersection Types</h2>\n<p>Intersection types are closely related to union types, but they are used very differently.\nAn intersection type combines multiple types into one.\nThis allows you to add together existing types to get a single type that has all the features you need.\nFor example, <code>Person &#x26; Serializable &#x26; Loggable</code> is a type which is all of <code>Person</code> <em>and</em> <code>Serializable</code> <em>and</em> <code>Loggable</code>.\nThat means an object of this type will have all members of all three types.</p>\n<p>For example, if you had networking requests with consistent error handling then you could separate out the error handling into it’s own type which is merged with types which correspond to a single response type.</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <data-lsp lsp='interface ErrorHandling'>ErrorHandling</data-lsp> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ErrorHandling.success: boolean'>success</data-lsp></span><span style=\"color: #000000\">: boolean;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ErrorHandling.error?: {&amp;#13;    message: string;&amp;#13;} | undefined'>error</data-lsp></span><span style=\"color: #000000\">?: { </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) message: string'>message</data-lsp></span><span style=\"color: #000000\">: string };</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <data-lsp lsp='interface ArtworksData'>ArtworksData</data-lsp> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ArtworksData.artworks: {&amp;#13;    title: string;&amp;#13;}[]'>artworks</data-lsp></span><span style=\"color: #000000\">: { </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) title: string'>title</data-lsp></span><span style=\"color: #000000\">: string }[];</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <data-lsp lsp='interface ArtistsData'>ArtistsData</data-lsp> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ArtistsData.artists: {&amp;#13;    name: string;&amp;#13;}[]'>artists</data-lsp></span><span style=\"color: #000000\">: { </span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) name: string'>name</data-lsp></span><span style=\"color: #000000\">: string }[];</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// These interfaces are composed to have</span>\n<span style=\"color: #008000\">// consistent error handling, and their own data.</span>\n\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> <data-lsp lsp='type ArtworksResponse = ArtworksData &amp;amp; ErrorHandling'>ArtworksResponse</data-lsp> = <data-lsp lsp='interface ArtworksData'>ArtworksData</data-lsp> &amp; <data-lsp lsp='interface ErrorHandling'>ErrorHandling</data-lsp>;</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> <data-lsp lsp='type ArtistsResponse = ArtistsData &amp;amp; ErrorHandling'>ArtistsResponse</data-lsp> = <data-lsp lsp='interface ArtistsData'>ArtistsData</data-lsp> &amp; <data-lsp lsp='interface ErrorHandling'>ErrorHandling</data-lsp>;</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> </span><span style=\"color: #1A1A1A\"><data-lsp lsp='const handleArtistsResponse: (response: ArtistsResponse) => void'>handleArtistsResponse</data-lsp> </span><span style=\"color: #000000\">= (</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) response: ArtistsResponse'>response</data-lsp></span><span style=\"color: #000000\">: <data-lsp lsp='type ArtistsResponse = ArtistsData &amp;amp; ErrorHandling'>ArtistsResponse</data-lsp>) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) response: ArtistsResponse'>response</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ErrorHandling.error?: {&amp;#13;    message: string;&amp;#13;} | undefined'>error</data-lsp></span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    <data-lsp lsp='var console: Console'>console</data-lsp>.<data-lsp lsp='(method) Console.error(...data: any[]): void'>error</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) response: ArtistsResponse'>response</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ErrorHandling.error?: {&amp;#13;    message: string;&amp;#13;}'>error</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) message: string'>message</data-lsp></span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  <data-lsp lsp='var console: Console'>console</data-lsp>.<data-lsp lsp='(method) Console.log(...data: any[]): void'>log</data-lsp>(</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(parameter) response: ArtistsResponse'>response</data-lsp></span><span style=\"color: #000000\">.</span><span style=\"color: #1A1A1A\"><data-lsp lsp='(property) ArtistsData.artists: {&amp;#13;    name: string;&amp;#13;}[]'>artists</data-lsp></span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">};</span></code><a href='https://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgKJSgeygCTiAEwBtQBzZAbwChlkBnAVwSTroC5kAjTTIifANw1k0LFAD8HCsgC2EVnFIQOdMFDLIAvkM1UqoSLEQoAglDAB3bAGs6AEThg4lYXHNWotqcjDAwfFTUNTQBtAF0dPQNoeCRkM19Ve0dnalo3RLB2SmQQODlA9RByUIiqXSoAekrkABUAC3kUaKMWZDcUBEwZAAdMOggCH0xkergANwgqmq6QOmBVCHARDGxR-GIyABp2wh9G4ChkTAsQZAIUgDo9MABPHtN3GzoAJXk+uZQAXninz2SnMgAGRoVa4DYkYpCO4PX6ZV7vTCfZA-BILLIOQEg9BiPCESGkIRUWaqdb4iBopJvOgfAYo5AACigiM+HEpWWptIgAEoUQA+Fy0YAwRnMmlIgaXUTYXlpWjIEm8CBSsFMlmS6VQS5yBRKblCeXIZlgBhQEAGrR6WiKviXIiYUhq8WfS4ZdF0fXlARAA'>Try</a></div></pre>","headings":[{"value":"Union Types","depth":2},{"value":"Unions with Common Fields","depth":2},{"value":"Discriminating Unions","depth":2},{"value":"Union Exhaustiveness checking","depth":2},{"value":"Intersection Types","depth":2}],"frontmatter":{"permalink":"/docs/handbook/unions-and-intersections.html","title":"Unions and Intersection Types","disable_toc":null,"oneline":"How to use unions and intersection types in TypeScript"}},"prev":{"childMarkdownRemark":{"frontmatter":{"title":"Literal Types","oneline":"Using literal types with TypeScript","permalink":"/docs/handbook/literal-types.html"}}},"next":{"childMarkdownRemark":{"frontmatter":{"title":"Classes","oneline":"How classes work in TypeScript","permalink":"/docs/handbook/classes.html"}}}},"pageContext":{"id":"unions-and-intersection-types","slug":"/docs/handbook/unions-and-intersections.html","repoPath":"/packages/documentation/copy/en/handbook-v1/Unions and Intersections.md","previousID":"ef891efb-46fb-5e86-89f7-924776beab3d","nextID":"043b288a-ecd2-54c6-a0a8-02ef3db2bf7b","lang":"en","modifiedTime":"2020-08-18T13:59:43.508Z"}}}