{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/declaration-files/deep-dive.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":"2d11c358-95f6-5c03-92ba-1fc470c227a8","excerpt":"Definition File Theory: A Deep Dive Structuring modules to give the exact API shape you want can be tricky.\nFor example, we might want a module that can be…","html":"<h1 id=\"definition-file-theory-a-deep-dive\" style=\"position:relative;\"><a href=\"#definition-file-theory-a-deep-dive\" aria-label=\"definition file theory a deep dive 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>Definition File Theory: A Deep Dive</h1>\n<p>Structuring modules to give the exact API shape you want can be tricky.\nFor example, we might want a module that can be invoked with or without <code>new</code> to produce different types,\nhas a variety of named types exposed in a hierarchy,\nand has some properties on the module object as well.</p>\n<p>By reading this guide, you’ll have the tools to write complex definition files that expose a friendly API surface.\nThis guide focuses on module (or UMD) libraries because the options here are more varied.</p>\n<h2 id=\"key-concepts\" style=\"position:relative;\"><a href=\"#key-concepts\" aria-label=\"key concepts 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>Key Concepts</h2>\n<p>You can fully understand how to make any shape of definition\nby understanding some key concepts of how TypeScript works.</p>\n<h3 id=\"types\" style=\"position:relative;\"><a href=\"#types\" aria-label=\"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>Types</h3>\n<p>If you’re reading this guide, you probably already roughly know what a type in TypeScript is.\nTo be more explicit, though, a <em>type</em> is introduced with:</p>\n<ul>\n<li>A type alias declaration (<code>type sn = number | string;</code>)</li>\n<li>An interface declaration (<code>interface I { x: number[]; }</code>)</li>\n<li>A class declaration (<code>class C { }</code>)</li>\n<li>An enum declaration (<code>enum E { A, B, C }</code>)</li>\n<li>An <code>import</code> declaration which refers to a type</li>\n</ul>\n<p>Each of these declaration forms creates a new type name.</p>\n<h3 id=\"values\" style=\"position:relative;\"><a href=\"#values\" aria-label=\"values 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>Values</h3>\n<p>As with types, you probably already understand what a value is.\nValues are runtime names that we can reference in expressions.\nFor example <code>let x = 5;</code> creates a value called <code>x</code>.</p>\n<p>Again, being explicit, the following things create values:</p>\n<ul>\n<li><code>let</code>, <code>const</code>, and <code>var</code> declarations</li>\n<li>A <code>namespace</code> or <code>module</code> declaration which contains a value</li>\n<li>An <code>enum</code> declaration</li>\n<li>A <code>class</code> declaration</li>\n<li>An <code>import</code> declaration which refers to a value</li>\n<li>A <code>function</code> declaration</li>\n</ul>\n<h3 id=\"namespaces\" style=\"position:relative;\"><a href=\"#namespaces\" aria-label=\"namespaces permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Namespaces</h3>\n<p>Types can exist in <em>namespaces</em>.\nFor example, if we have the declaration <code>let x: A.B.C</code>,\nwe say that the type <code>C</code> comes from the <code>A.B</code> namespace.</p>\n<p>This distinction is subtle and important — here, <code>A.B</code> is not necessarily a type or a value.</p>\n<h2 id=\"simple-combinations-one-name-multiple-meanings\" style=\"position:relative;\"><a href=\"#simple-combinations-one-name-multiple-meanings\" aria-label=\"simple combinations one name multiple meanings 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>Simple Combinations: One name, multiple meanings</h2>\n<p>Given a name <code>A</code>, we might find up to three different meanings for <code>A</code>: a type, a value or a namespace.\nHow the name is interpreted depends on the context in which it is used.\nFor example, in the declaration <code>let m: A.A = A;</code>,\n<code>A</code> is used first as a namespace, then as a type name, then as a value.\nThese meanings might end up referring to entirely different declarations!</p>\n<p>This may seem confusing, but it’s actually very convenient as long as we don’t excessively overload things.\nLet’s look at some useful aspects of this combining behavior.</p>\n<h3 id=\"built-in-combinations\" style=\"position:relative;\"><a href=\"#built-in-combinations\" aria-label=\"built in combinations 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>Built-in Combinations</h3>\n<p>Astute readers will notice that, for example, <code>class</code> appeared in both the <em>type</em> and <em>value</em> lists.\nThe declaration <code>class C { }</code> creates two things:\na <em>type</em> <code>C</code> which refers to the instance shape of the class,\nand a <em>value</em> <code>C</code> which refers to the constructor function of the class.\nEnum declarations behave similarly.</p>\n<h3 id=\"user-combinations\" style=\"position:relative;\"><a href=\"#user-combinations\" aria-label=\"user combinations 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>User Combinations</h3>\n<p>Let’s say we wrote a module file <code>foo.d.ts</code>:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> SomeVar: { a: SomeType };</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> SomeType {</span>\n<span style=\"color: #000000\">  count: number;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Then consumed it:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">*</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">as</span><span style=\"color: #000000\"> foo </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">'./foo'</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x: foo.SomeType = foo.SomeVar.a;</span>\n<span style=\"color: #000000\">console.log(x.count);</span></code></div></pre>\n<p>This works well enough, but we might imagine that <code>SomeType</code> and <code>SomeVar</code> were very closely related\nsuch that you’d like them to have the same name.\nWe can use combining to present these two different objects (the value and the type) under the same name <code>Bar</code>:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> Bar: { a: Bar };</span>\n<span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Bar {</span>\n<span style=\"color: #000000\">  count: number;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>This presents a very good opportunity for destructuring in the consuming code:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> { Bar } </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">'./foo'</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x: Bar = Bar.a;</span>\n<span style=\"color: #000000\">console.log(x.count);</span></code></div></pre>\n<p>Again, we’ve used <code>Bar</code> as both a type and a value here.\nNote that we didn’t have to declare the <code>Bar</code> value as being of the <code>Bar</code> type — they’re independent.</p>\n<h2 id=\"advanced-combinations\" style=\"position:relative;\"><a href=\"#advanced-combinations\" aria-label=\"advanced combinations 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>Advanced Combinations</h2>\n<p>Some kinds of declarations can be combined across multiple declarations.\nFor example, <code>class C { }</code> and <code>interface C { }</code> can co-exist and both contribute properties to the <code>C</code> types.</p>\n<p>This is legal as long as it does not create a conflict.\nA general rule of thumb is that values always conflict with other values of the same name unless they are declared as <code>namespace</code>s,\ntypes will conflict if they are declared with a type alias declaration (<code>type s = string</code>),\nand namespaces never conflict.</p>\n<p>Let’s see how this can be used.</p>\n<h3 id=\"adding-using-an-interface\" style=\"position:relative;\"><a href=\"#adding-using-an-interface\" aria-label=\"adding using an interface 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>Adding using an <code>interface</code></h3>\n<p>We can add additional members to an <code>interface</code> with another <code>interface</code> declaration:</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\"> Foo {</span>\n<span style=\"color: #000000\">  x: number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #008000\">// ... elsewhere ...</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Foo {</span>\n<span style=\"color: #000000\">  y: number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a: Foo = ...;</span>\n<span style=\"color: #000000\">console.log(a.x + a.y); </span><span style=\"color: #008000\">// OK</span></code></div></pre>\n<p>This also works with classes:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Foo {</span>\n<span style=\"color: #000000\">  x: number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #008000\">// ... elsewhere ...</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Foo {</span>\n<span style=\"color: #000000\">  y: number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a: Foo = ...;</span>\n<span style=\"color: #000000\">console.log(a.x + a.y); </span><span style=\"color: #008000\">// OK</span></code></div></pre>\n<p>Note that we cannot add to type aliases (<code>type s = string;</code>) using an interface.</p>\n<h3 id=\"adding-using-a-namespace\" style=\"position:relative;\"><a href=\"#adding-using-a-namespace\" aria-label=\"adding using a namespace 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>Adding using a <code>namespace</code></h3>\n<p>A <code>namespace</code> declaration can be used to add new types, values, and namespaces in any way which does not create a conflict.</p>\n<p>For example, we can add a static member to a class:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #008000\">// ... elsewhere ...</span>\n<span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x: number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> y = C.x; </span><span style=\"color: #008000\">// OK</span></code></div></pre>\n<p>Note that in this example, we added a value to the <em>static</em> side of <code>C</code> (its constructor function).\nThis is because we added a <em>value</em>, and the container for all values is another value\n(types are contained by namespaces, and namespaces are contained by other namespaces).</p>\n<p>We could also add a namespaced type to a class:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #008000\">// ... elsewhere ...</span>\n<span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> D { }</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> y: C.D; </span><span style=\"color: #008000\">// OK</span></code></div></pre>\n<p>In this example, there wasn’t a namespace <code>C</code> until we wrote the <code>namespace</code> declaration for it.\nThe meaning <code>C</code> as a namespace doesn’t conflict with the value or type meanings of <code>C</code> created by the class.</p>\n<p>Finally, we could perform many different merges using <code>namespace</code> declarations.\nThis isn’t a particularly realistic example, but shows all sorts of interesting behavior:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> X {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Y { }</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Z { }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// ... elsewhere ...</span>\n<span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> X {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> Y: number;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> Z {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">export</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C { }</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> X = string;</span></code></div></pre>\n<p>In this example, the first block creates the following name meanings:</p>\n<ul>\n<li>A value <code>X</code> (because the <code>namespace</code> declaration contains a value, <code>Z</code>)</li>\n<li>A namespace <code>X</code> (because the <code>namespace</code> declaration contains a type, <code>Y</code>)</li>\n<li>A type <code>Y</code> in the <code>X</code> namespace</li>\n<li>A type <code>Z</code> in the <code>X</code> namespace (the instance shape of the class)</li>\n<li>A value <code>Z</code> that is a property of the <code>X</code> value (the constructor function of the class)</li>\n</ul>\n<p>The second  block creates the following name meanings:</p>\n<ul>\n<li>A value <code>Y</code> (of type <code>number</code>) that is a property of the <code>X</code> value</li>\n<li>A namespace <code>Z</code></li>\n<li>A value <code>Z</code> that is a property of the <code>X</code> value</li>\n<li>A type <code>C</code> in the <code>X.Z</code> namespace</li>\n<li>A value <code>C</code> that is a property of the <code>X.Z</code> value</li>\n<li>A type <code>X</code></li>\n</ul>\n<h2 id=\"using-with-export--or-import\" style=\"position:relative;\"><a href=\"#using-with-export--or-import\" aria-label=\"using with export  or import 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>Using with <code>export =</code> or <code>import</code></h2>\n<p>An important rule is that <code>export</code> and <code>import</code> declarations export or import <em>all meanings</em> of their targets.</p>\n<!-- TODO: Write more on that. -->","headings":[{"value":"Definition File Theory: A Deep Dive","depth":1},{"value":"Key Concepts","depth":2},{"value":"Types","depth":3},{"value":"Values","depth":3},{"value":"Namespaces","depth":3},{"value":"Simple Combinations: One name, multiple meanings","depth":2},{"value":"Built-in Combinations","depth":3},{"value":"User Combinations","depth":3},{"value":"Advanced Combinations","depth":2},{"value":"Adding using an interface","depth":3},{"value":"Adding using a namespace","depth":3},{"value":"Using with export = or import","depth":2}],"frontmatter":{"permalink":"/docs/handbook/declaration-files/deep-dive.html","title":"Deep Dive"}}},"pageContext":{"slug":"/docs/handbook/declaration-files/deep-dive.html","isOldHandbook":true}}}