{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/unions-and-intersections.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":"147eacea-38b5-554d-a387-2aa28f8dc091","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<h1 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</h1>\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\"><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 'padding' is a string, then 'padding' is appended to the left side.</span>\n<span style=\"color: #008000\"> * If 'padding' 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\"> padLeft(value: string, padding: 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\"> padding === </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\"> Array(padding + </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">).join(</span><span style=\"color: #A31515\">\" \"</span><span style=\"color: #000000\">) + value;</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\"> padding === </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\"> padding + value;</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\"> Error(</span><span style=\"color: #A31515\">`Expected string or number, got '</span><span style=\"color: #0000FF\">${</span><span style=\"color: #A31515\">padding</span><span style=\"color: #0000FF\">}</span><span style=\"color: #A31515\">'.`</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">padLeft(</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></div></pre>\n<p>The problem with <code>padLeft</code> 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\"><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\"> indentedString = padLeft(</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></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\"><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 'padding' is a string, then 'padding' is appended to the left side.</span>\n<span style=\"color: #008000\"> * If 'padding' 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\"> padLeft(value: string, padding: 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\"> indentedString = padLeft(</span><span style=\"color: #A31515\">\"Hello world\"</span><span style=\"color: #000000\">, </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// errors during compilation</span></code></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<p>If we have a value that has a union type, we can only access members that are common to all types in the union.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Bird {</span>\n<span style=\"color: #000000\">  fly();</span>\n<span style=\"color: #000000\">  layEggs();</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Fish {</span>\n<span style=\"color: #000000\">  swim();</span>\n<span style=\"color: #000000\">  layEggs();</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> getSmallPet(): Fish | Bird {</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\"> pet = getSmallPet();</span>\n<span style=\"color: #000000\">pet.layEggs(); </span><span style=\"color: #008000\">// okay</span>\n<span style=\"color: #000000\">pet.swim(); </span><span style=\"color: #008000\">// errors</span></code></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<h1 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</h1>\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>Here’s a simple example that shows how to create a mixin:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> extend&lt;First, Second&gt;(first: First, second: Second): First & Second {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> result: Partial&lt;First & Second&gt; = {};</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> prop </span><span style=\"color: #0000FF\">in</span><span style=\"color: #000000\"> first) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (first.hasOwnProperty(prop)) {</span>\n<span style=\"color: #000000\">      (result </span><span style=\"color: #0000FF\">as</span><span style=\"color: #000000\"> First)[prop] = first[prop];</span>\n<span style=\"color: #000000\">    }</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> prop </span><span style=\"color: #0000FF\">in</span><span style=\"color: #000000\"> second) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (second.hasOwnProperty(prop)) {</span>\n<span style=\"color: #000000\">      (result </span><span style=\"color: #0000FF\">as</span><span style=\"color: #000000\"> Second)[prop] = second[prop];</span>\n<span style=\"color: #000000\">    }</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> result </span><span style=\"color: #0000FF\">as</span><span style=\"color: #000000\"> First & Second;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Person {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">constructor</span><span style=\"color: #000000\">(</span><span style=\"color: #0000FF\">public</span><span style=\"color: #000000\"> name: string) {}</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Loggable {</span>\n<span style=\"color: #000000\">  log(name: string): void;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> ConsoleLogger </span><span style=\"color: #0000FF\">implements</span><span style=\"color: #000000\"> Loggable {</span>\n<span style=\"color: #000000\">  log(name) {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">`Hello, I'm </span><span style=\"color: #0000FF\">${</span><span style=\"color: #A31515\">name</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>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> jim = extend(</span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> Person(</span><span style=\"color: #A31515\">\"Jim\"</span><span style=\"color: #000000\">), ConsoleLogger.prototype);</span>\n<span style=\"color: #000000\">jim.log(jim.name);</span></code></div></pre>","headings":[{"value":"Union Types","depth":1},{"value":"Intersection Types","depth":1}],"frontmatter":{"permalink":"/docs/handbook/unions-and-intersections.html","title":"Unions and Intersection Types"}}},"pageContext":{"slug":"/docs/handbook/unions-and-intersections.html","isOldHandbook":true}}}