{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/typescript-in-5-minutes-func.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":"322f1de9-13c0-50ba-bf0a-4fe25650c23f","excerpt":"TypeScript began its life as an attempt to bring traditional object-oriented types\nto JavaScript so that the programmers at Microsoft could bring\ntraditional…","html":"<p>TypeScript began its life as an attempt to bring traditional object-oriented types\nto JavaScript so that the programmers at Microsoft could bring\ntraditional object-oriented programs to the web. As it has developed, TypeScript’s type\nsystem has evolved to model code written by native JavaScripters. The\nresulting system is powerful, interesting and messy.</p>\n<p>This introduction is designed for working Haskell or ML programmers\nwho want to learn TypeScript. It describes how the type system of\nTypeScript differs from Haskell’s type system. It also describes\nunique features of TypeScript’s type system that arise from its\nmodelling of JavaScript code.</p>\n<p>This introduction does not cover object-oriented programming. In\npractice, object-oriented programs in TypeScript are similar to those\nin other popular languages with OO features.</p>\n<h1 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites 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>Prerequisites</h1>\n<p>In this introduction, I assume you know the following:</p>\n<ul>\n<li>How to program in JavaScript, the good parts.</li>\n<li>Type syntax of a C-descended language.</li>\n</ul>\n<p>If you need to learn the good parts of JavaScript, read\n<a href=\"http://shop.oreilly.com/product/9780596517748.do\">JavaScript: The Good Parts</a>.\nYou may be able to skip the book if you know how to write programs in\na call-by-value lexically scoped language with lots of mutability and\nnot much else.\n<a href=\"https://people.csail.mit.edu/jaffer/r4rs.pdf\">R<sup>4</sup>RS Scheme</a> is a good example.</p>\n<p><a href=\"http://www.stroustrup.com/4th.html\">The C++ Programming Language</a> is\na good place to learn about C-style type syntax. Unlike C++,\nTypeScript uses postfix types, like so: <code>x: string</code> instead of <code>string x</code>.</p>\n<h1 id=\"concepts-not-in-haskell\" style=\"position:relative;\"><a href=\"#concepts-not-in-haskell\" aria-label=\"concepts not in haskell 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>Concepts not in Haskell</h1>\n<h2 id=\"built-in-types\" style=\"position:relative;\"><a href=\"#built-in-types\" aria-label=\"built in 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>Built-in types</h2>\n<p>JavaScript defines 7 built-in types:</p>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Explanation</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Number</code></td>\n<td>a double-precision IEEE 754 floating point.</td>\n</tr>\n<tr>\n<td><code>String</code></td>\n<td>an immutable UTF-16 string.</td>\n</tr>\n<tr>\n<td><code>Boolean</code></td>\n<td><code>true</code> and <code>false</code>.</td>\n</tr>\n<tr>\n<td><code>Symbol</code></td>\n<td>a unique value usually used as a key.</td>\n</tr>\n<tr>\n<td><code>Null</code></td>\n<td>equivalent to the unit type.</td>\n</tr>\n<tr>\n<td><code>Undefined</code></td>\n<td>also equivalent to the unit type.</td>\n</tr>\n<tr>\n<td><code>Object</code></td>\n<td>similar to records.</td>\n</tr>\n</tbody>\n</table>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures\">See the MDN page for more detail</a>.</p>\n<p>TypeScript has corresponding primitive types for the built-in types:</p>\n<ul>\n<li><code>number</code></li>\n<li><code>string</code></li>\n<li><code>boolean</code></li>\n<li><code>symbol</code></li>\n<li><code>null</code></li>\n<li><code>undefined</code></li>\n<li><code>object</code></li>\n</ul>\n<h3 id=\"other-important-typescript-types\" style=\"position:relative;\"><a href=\"#other-important-typescript-types\" aria-label=\"other important typescript 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>Other important Typescript types</h3>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Explanation</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>unknown</code></td>\n<td>the top type.</td>\n</tr>\n<tr>\n<td><code>never</code></td>\n<td>the bottom type.</td>\n</tr>\n<tr>\n<td>object literal</td>\n<td>eg <code>{ property: Type }</code></td>\n</tr>\n<tr>\n<td><code>void</code></td>\n<td>a subtype of <code>undefined</code> intended for use as a return type.</td>\n</tr>\n<tr>\n<td><code>T[]</code></td>\n<td>mutable arrays, also written <code>Array&#x3C;T></code></td>\n</tr>\n<tr>\n<td><code>[T, T]</code></td>\n<td>tuples, which are fixed-length but mutable</td>\n</tr>\n<tr>\n<td><code>(t: T) => U</code></td>\n<td>functions</td>\n</tr>\n</tbody>\n</table>\n<p>Notes:</p>\n<ol>\n<li>\n<p>Function syntax includes parameter names. This is pretty hard to get used to!</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> fst: (a: any, d: any) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> any = (a, d) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> a;</span>\n<span style=\"color: #008000\">// or more precisely:</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> snd: &lt;T, U&gt;(a: T, d: U) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> U = (a, d) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> d.</span></code></div></pre>\n</li>\n<li>\n<p>Object literal type syntax closely mirrors object literal value syntax:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> o: { n: number; xs: object[] } = { n: </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, xs: [] };</span></code></div></pre>\n</li>\n<li><code>[T, T]</code> is a subtype of <code>T[]</code>. This is different than Haskell, where tuples are not related to lists.</li>\n</ol>\n<h3 id=\"boxed-types\" style=\"position:relative;\"><a href=\"#boxed-types\" aria-label=\"boxed 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>Boxed types</h3>\n<p>JavaScript has boxed equivalents of primitive types that contain the\nmethods that programmers associate with those types. TypeScript\nreflects this with, for example, the difference between the primitive\ntype <code>number</code> and the boxed type <code>Number</code>. The boxed types are rarely\nneeded, since their methods return primitives.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">(</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">).toExponential();</span>\n<span style=\"color: #008000\">// equivalent to</span>\n<span style=\"color: #000000\">Number.prototype.toExponential.call(</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">);</span></code></div></pre>\n<p>Note that calling methods on numeric literals requires an additional\n<code>.</code> to aid the parser.</p>\n<h2 id=\"gradual-typing\" style=\"position:relative;\"><a href=\"#gradual-typing\" aria-label=\"gradual typing 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>Gradual typing</h2>\n<p>TypeScript uses the type <code>any</code> whenever it can’t tell what the type of\nan expression should be. Compared to <code>Dynamic</code>, calling <code>any</code> a type\nis an overstatement. It just turns off the type checker\nwherever it appears. For example, you can push any value into an\n<code>any[]</code> without marking the value in any way:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// with \"noImplicitAny\": false in tsconfig.json, anys: any[]</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> <span class='lsp'>anys <span class='lsp-result'>const anys: any[]</span></span>= [];</span>\n<span style=\"color: #000000\"><span class='lsp'>anys.<span class='lsp-result'>const anys: any[]</span></span><span class='lsp'>push(<span class='lsp-result'>(method) Array&lt;any&gt;.push(...items: any[]): number</span></span></span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\"><span class='lsp'>anys.<span class='lsp-result'>const anys: any[]</span></span><span class='lsp'>push(<span class='lsp-result'>(method) Array&lt;any&gt;.push(...items: any[]): number</span></span></span><span style=\"color: #A31515\">\"oh no\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\"><span class='lsp'>anys.<span class='lsp-result'>const anys: any[]</span></span><span class='lsp'>push(<span class='lsp-result'>(method) Array&lt;any&gt;.push(...items: any[]): number</span></span>{ <span class='lsp'>anything:<span class='lsp-result'>(property) anything: string</span></span></span><span style=\"color: #A31515\">\"goes\"</span><span style=\"color: #000000\"> });</span></code></div></pre>\n<p>And you can use an expression of type <code>any</code> anywhere:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">anys.map(anys[</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">]); </span><span style=\"color: #008000\">// oh no, \"oh no\" is not a function</span></code></div></pre>\n<p><code>any</code> is contagious, too — if you initialise a variable with an\nexpression of type <code>any</code>, the variable has type <code>any</code> too.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> sepsis = anys[</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">] + anys[</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">]; </span><span style=\"color: #008000\">// this could mean anything</span></code></div></pre>\n<p>To get an error when TypeScript produces an <code>any</code>, use\n<code>\"noImplicitAny\": true</code>, or <code>\"strict\": true</code> in <code>tsconfig.json</code>.</p>\n<h2 id=\"structural-typing\" style=\"position:relative;\"><a href=\"#structural-typing\" aria-label=\"structural typing 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>Structural typing</h2>\n<p>Structural typing is a familiar concept to most functional\nprogrammers, although Haskell and most MLs are not\nstructurally typed. Its basic form is pretty simple:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// @strict: false</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> o = { x: </span><span style=\"color: #A31515\">\"hi\"</span><span style=\"color: #000000\">, extra: </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> }; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> o2: { x: string } = o; </span><span style=\"color: #008000\">// ok</span></code></div></pre>\n<p>Here, the object literal <code>{ x: \"hi\", extra: 1 }</code> has a matching\nliteral type <code>{ x: string, extra: number }</code>. That\ntype is assignable to <code>{ x: string }</code> since\nit has all the required properties and those properties have\nassignable types. The extra property doesn’t prevent assignment, it\njust makes it a subtype of <code>{ x: string }</code>.</p>\n<p>Named types just give a name to a type; for assignability purposes\nthere’s no difference between the type alias <code>One</code> and the interface\ntype <code>Two</code> below. They both have a property <code>p: string</code>. (Type alises\nbehave differently than interfaces with respect to recursive\ndefinitions and type parameters, however.)</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\"> <span class='lsp'>One <span class='lsp-result'>type One = {&#13;    p: string;&#13;}</span></span>= { <span class='lsp'>p:<span class='lsp-result'>(property) p: string</span></span> string };</span>\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> <span class='lsp'>Two <span class='lsp-result'>interface Two</span></span></span>\n<span style=\"color: #000000\">  <span class='lsp'>p:<span class='lsp-result'>(property) Two.p: string</span></span> string;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> <span class='lsp'>Three <span class='lsp-result'>class Three</span></span></span>\n<span style=\"color: #000000\">  <span class='lsp'>p <span class='lsp-result'>(property) Three.p: string</span></span>= </span><span style=\"color: #A31515\">\"Hello\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> <span class='lsp'>x:<span class='lsp-result'>let x: One</span></span> <span class='lsp'>One <span class='lsp-result'>type One = {&#13;    p: string;&#13;}</span></span>= { <span class='lsp'>p:<span class='lsp-result'>(property) p: string</span></span></span><span style=\"color: #A31515\">\"hi\"</span><span style=\"color: #000000\"> };</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> <span class='lsp'>two:<span class='lsp-result'>let two: Two</span></span> <span class='lsp'>Two <span class='lsp-result'>interface Two</span></span>= <span class='lsp'>x;<span class='lsp-result'>let x: One</span></span></span>\n<span style=\"color: #000000\"><span class='lsp'>two <span class='lsp-result'>let two: Two</span></span>= </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> <span class='lsp'>Three(<span class='lsp-result'>constructor Three(): Three</span></span>);</span></code></div></pre>\n<h2 id=\"unions\" style=\"position:relative;\"><a href=\"#unions\" aria-label=\"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>Unions</h2>\n<p>In TypeScript, union types are untagged. In other words, they are not\ndiscriminated unions like <code>data</code> in Haskell. However, you can often\ndiscriminate types in a union using built-in tags or other properties.</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\"> <span class='lsp'>start(<span class='lsp-result'>function start(arg: string | string[] | (() =&gt; string) | {&#13;    s: string;&#13;}): string</span></span></span>\n<span style=\"color: #000000\">  <span class='lsp'>arg:<span class='lsp-result'>(parameter) arg: string | string[] | (() =&gt; string) | {&#13;    s: string;&#13;}</span></span> string | string[] | (() </span><span style=\"color: #0000FF\">=></span><span style=\"color: #000000\"> string) | { <span class='lsp'>s:<span class='lsp-result'>(property) s: string</span></span> string }</span>\n<span style=\"color: #000000\">): string {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// this is super common in JavaScript</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 class='lsp'>arg <span class='lsp-result'>(parameter) arg: string | string[] | (() =&gt; string) | {&#13;    s: string;&#13;}</span></span>=== </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 class='lsp'>commonCase(<span class='lsp-result'>(local function) commonCase(s: string): string</span></span><span class='lsp'>arg)<span class='lsp-result'>(parameter) arg: string</span></span></span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (<span class='lsp'>Array.<span class='lsp-result'>var Array: ArrayConstructor</span></span><span class='lsp'>isArray(<span class='lsp-result'>(method) ArrayConstructor.isArray(arg: any): arg is any[]</span></span><span class='lsp'>arg)<span class='lsp-result'>(parameter) arg: string[] | (() =&gt; string) | {&#13;    s: string;&#13;}</span></span>) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <span class='lsp'>arg.<span class='lsp-result'>(parameter) arg: string[]</span></span><span class='lsp'>map(<span class='lsp-result'>(method) Array&lt;string&gt;.map&lt;string&gt;(callbackfn: (value: string, index: number, array: string[]) =&gt; string, thisArg?: any): string[]</span></span><span class='lsp'>commonCase)<span class='lsp-result'>(local function) commonCase(s: string): string</span></span>.<span class='lsp'>join(<span class='lsp-result'>(method) Array&lt;string&gt;.join(separator?: string | undefined): string</span></span></span><span style=\"color: #A31515\">\",\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><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 class='lsp'>arg <span class='lsp-result'>(parameter) arg: (() =&gt; string) | {&#13;    s: string;&#13;}</span></span>=== </span><span style=\"color: #A31515\">\"function\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <span class='lsp'>commonCase(<span class='lsp-result'>(local function) commonCase(s: string): string</span></span><span class='lsp'>arg(<span class='lsp-result'>(parameter) arg: () =&gt; string</span></span>));</span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <span class='lsp'>commonCase(<span class='lsp-result'>(local function) commonCase(s: string): string</span></span><span class='lsp'>arg.<span class='lsp-result'>(parameter) arg: {&#13;    s: string;&#13;}</span></span><span class='lsp'>s)<span class='lsp-result'>(property) s: string</span></span></span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>commonCase(<span class='lsp-result'>(local function) commonCase(s: string): string</span></span><span class='lsp'>s:<span class='lsp-result'>(parameter) s: string</span></span> string): string {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// finally, just convert a string to another string</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <span class='lsp'>s;<span class='lsp-result'>(parameter) s: string</span></span></span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p><code>string</code>, <code>Array</code> and <code>Function</code> have built-in type predicates,\nconveniently leaving the object type for the <code>else</code> branch. It is\npossible, however, to generate unions that are difficult to\ndifferentiate at runtime. For new code, it’s best to build only\ndiscriminated unions.</p>\n<p>The following types have built-in predicates:</p>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Predicate</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>string</td>\n<td><code>typeof s === \"string\"</code></td>\n</tr>\n<tr>\n<td>number</td>\n<td><code>typeof n === \"number\"</code></td>\n</tr>\n<tr>\n<td>bigint</td>\n<td><code>typeof m === \"bigint\"</code></td>\n</tr>\n<tr>\n<td>boolean</td>\n<td><code>typeof b === \"boolean\"</code></td>\n</tr>\n<tr>\n<td>symbol</td>\n<td><code>typeof g === \"symbol\"</code></td>\n</tr>\n<tr>\n<td>undefined</td>\n<td><code>typeof undefined === \"undefined\"</code></td>\n</tr>\n<tr>\n<td>function</td>\n<td><code>typeof f === \"function\"</code></td>\n</tr>\n<tr>\n<td>array</td>\n<td><code>Array.isArray(a)</code></td>\n</tr>\n<tr>\n<td>object</td>\n<td><code>typeof o === \"object\"</code></td>\n</tr>\n</tbody>\n</table>\n<p>Note that functions and arrays are objects at runtime, but have their\nown predicates.</p>\n<h3 id=\"intersections\" style=\"position:relative;\"><a href=\"#intersections\" aria-label=\"intersections 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>Intersections</h3>\n<p>In addition to unions, TypeScript also has intersections:</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\"> <span class='lsp'>Combined <span class='lsp-result'>type Combined = {&#13;    a: number;&#13;} &amp; {&#13;    b: string;&#13;}</span></span>= { <span class='lsp'>a:<span class='lsp-result'>(property) a: number</span></span> number } &amp; { <span class='lsp'>b:<span class='lsp-result'>(property) b: string</span></span> string };</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> <span class='lsp'>Conflicting <span class='lsp-result'>type Conflicting = {&#13;    a: number;&#13;} &amp; {&#13;    a: string;&#13;}</span></span>= { <span class='lsp'>a:<span class='lsp-result'>(property) a: number</span></span> number } &amp; { <span class='lsp'>a:<span class='lsp-result'>(property) a: string</span></span> string };</span></code></div></pre>\n<p><code>Combined</code> has two properties, <code>a</code> and <code>b</code>, just as if they had been\nwritten as one object literal type. Intersection and union are\nrecursive in case of conflicts, so <code>Conflicting.a: number &#x26; string</code>.</p>\n<h2 id=\"unit-types\" style=\"position:relative;\"><a href=\"#unit-types\" aria-label=\"unit 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>Unit types</h2>\n<p>Unit types are subtypes of primitive types that contain exactly one\nprimitive value. For example, the string <code>\"foo\"</code> has the type\n<code>\"foo\"</code>. Since JavaScript has no built-in enums, it is common to use a set of\nwell-known strings instead. Unions of string literal types allow\nTypeScript to type this pattern:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>pad(<span class='lsp-result'>function pad(s: string, n: number, direction: &quot;left&quot; | &quot;right&quot;): string</span></span><span class='lsp'>s:<span class='lsp-result'>(parameter) s: string</span></span> string, <span class='lsp'>n:<span class='lsp-result'>(parameter) n: number</span></span> number, <span class='lsp'>direction:<span class='lsp-result'>(parameter) direction: &quot;left&quot; | &quot;right&quot;</span></span></span><span style=\"color: #A31515\">\"left\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"right\"</span><span style=\"color: #000000\">): string;</span>\n<span style=\"color: #000000\"><span class='lsp'>pad(<span class='lsp-result'>function pad(s: string, n: number, direction: &quot;left&quot; | &quot;right&quot;): string</span></span></span><span style=\"color: #A31515\">\"hi\"</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"left\"</span><span style=\"color: #000000\">);</span></code></div></pre>\n<p>When needed, the compiler <em>widens</em> — converts to a\nsupertype — the unit type to the primitive type, such as <code>\"foo\"</code>\nto <code>string</code>. This happens when using mutability, which can hamper some\nuses of mutable variables:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> s = </span><span style=\"color: #A31515\">\"right\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">pad(</span><span style=\"color: #A31515\">\"hi\"</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">, s); </span><span style=\"color: #008000\">// error: 'string' is not assignable to '\"left\" | \"right\"'</span></code></div></pre>\n<p>Here’s how the error happens:</p>\n<ul>\n<li><code>\"right\": \"right\"</code></li>\n<li><code>s: string</code> because <code>\"right\"</code> widens to <code>string</code> on assignment to a mutable variable.</li>\n<li><code>string</code> is not assignable to <code>\"left\" | \"right\"</code></li>\n</ul>\n<p>You can work around this with a type annotation for <code>s</code>, but that\nin turn prevents assignments to <code>s</code> of variables that are not of type\n<code>\"left\" | \"right\"</code>.</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> s: </span><span style=\"color: #A31515\">\"left\"</span><span style=\"color: #000000\"> | </span><span style=\"color: #A31515\">\"right\"</span><span style=\"color: #000000\"> = </span><span style=\"color: #A31515\">\"right\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">pad(</span><span style=\"color: #A31515\">\"hi\"</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">, s);</span></code></div></pre>\n<h1 id=\"concepts-similar-to-haskell\" style=\"position:relative;\"><a href=\"#concepts-similar-to-haskell\" aria-label=\"concepts similar to haskell 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>Concepts similar to Haskell</h1>\n<h2 id=\"contextual-typing\" style=\"position:relative;\"><a href=\"#contextual-typing\" aria-label=\"contextual typing 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>Contextual typing</h2>\n<p>TypeScript has some obvious places where it can infer types, like\nvariable declarations:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> <span class='lsp'>s <span class='lsp-result'>let s: string</span></span>= </span><span style=\"color: #A31515\">\"I'm a string!\"</span><span style=\"color: #000000\">;</span></code></div></pre>\n<p>But it also infers types in a few other places that you may not expect\nif you’ve worked with other C-syntax languages:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>map&lt;<span class='lsp-result'>function map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span><span class='lsp'>T,<span class='lsp-result'>(type parameter) T in map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span> <span class='lsp'>U&gt;<span class='lsp-result'>(type parameter) U in map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span>(<span class='lsp'>f:<span class='lsp-result'>(parameter) f: (t: T) =&gt; U</span></span> (<span class='lsp'>t:<span class='lsp-result'>(parameter) t: T</span></span> <span class='lsp'>T)<span class='lsp-result'>(type parameter) T in map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span></span><span style=\"color: #0000FF\">=></span><span style=\"color: #000000\"> <span class='lsp'>U,<span class='lsp-result'>(type parameter) U in map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span> <span class='lsp'>ts:<span class='lsp-result'>(parameter) ts: T[]</span></span> <span class='lsp'>T[<span class='lsp-result'>(type parameter) T in map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span>]): <span class='lsp'>U[<span class='lsp-result'>(type parameter) U in map&lt;T, U&gt;(f: (t: T) =&gt; U, ts: T[]): U[]</span></span>];</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> <span class='lsp'>sns <span class='lsp-result'>let sns: string[]</span></span>= <span class='lsp'>map(<span class='lsp-result'>function map&lt;number, string&gt;(f: (t: number) =&gt; string, ts: number[]): string[]</span></span><span class='lsp'>n <span class='lsp-result'>(parameter) n: number</span></span></span><span style=\"color: #0000FF\">=></span><span style=\"color: #000000\"> <span class='lsp'>n.<span class='lsp-result'>(parameter) n: number</span></span><span class='lsp'>toString(<span class='lsp-result'>(method) Number.toString(radix?: number | undefined): string</span></span>), [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">]);</span></code></div></pre>\n<p>Here, <code>n: number</code> in this example also, despite the fact that <code>T</code> and <code>U</code>\nhave not been inferred before the call. In fact, after <code>[1,2,3]</code> has\nbeen used to infer <code>T=number</code>, the return type of <code>n => n.toString()</code>\nis used to infer <code>U=string</code>, causing <code>sns</code> to have the type\n<code>string[]</code>.</p>\n<p>Note that inference will work in any order, but intellisense will only\nwork left-to-right, so TypeScript prefers to declare <code>map</code> with the\narray first:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>map&lt;<span class='lsp-result'>function map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span><span class='lsp'>T,<span class='lsp-result'>(type parameter) T in map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span> <span class='lsp'>U&gt;<span class='lsp-result'>(type parameter) U in map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span>(<span class='lsp'>ts:<span class='lsp-result'>(parameter) ts: T[]</span></span> <span class='lsp'>T[<span class='lsp-result'>(type parameter) T in map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span>], <span class='lsp'>f:<span class='lsp-result'>(parameter) f: (t: T) =&gt; U</span></span> (<span class='lsp'>t:<span class='lsp-result'>(parameter) t: T</span></span> <span class='lsp'>T)<span class='lsp-result'>(type parameter) T in map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span></span><span style=\"color: #0000FF\">=></span><span style=\"color: #000000\"> <span class='lsp'>U)<span class='lsp-result'>(type parameter) U in map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span>: <span class='lsp'>U[<span class='lsp-result'>(type parameter) U in map&lt;T, U&gt;(ts: T[], f: (t: T) =&gt; U): U[]</span></span>];</span></code></div></pre>\n<p>Contextual typing also works recursively through object literals, and\non unit types that would otherwise be inferred as <code>string</code> or\n<code>number</code>. And it can infer return types from context:</p>\n<pre class=\"shiki twoslash\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>run&lt;<span class='lsp-result'>function run&lt;T&gt;(thunk: (t: T) =&gt; void): T</span></span><span class='lsp'>T&gt;<span class='lsp-result'>(type parameter) T in run&lt;T&gt;(thunk: (t: T) =&gt; void): T</span></span>(<span class='lsp'>thunk:<span class='lsp-result'>(parameter) thunk: (t: T) =&gt; void</span></span> (<span class='lsp'>t:<span class='lsp-result'>(parameter) t: T</span></span> <span class='lsp'>T)<span class='lsp-result'>(type parameter) T in run&lt;T&gt;(thunk: (t: T) =&gt; void): T</span></span></span><span style=\"color: #0000FF\">=></span><span style=\"color: #000000\"> void): <span class='lsp'>T;<span class='lsp-result'>(type parameter) T in run&lt;T&gt;(thunk: (t: T) =&gt; void): T</span></span></span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> <span class='lsp'>i:<span class='lsp-result'>let i: {&#13;    inference: string;&#13;}</span></span> { <span class='lsp'>inference:<span class='lsp-result'>(property) inference: string</span></span> string } = <span class='lsp'>run(<span class='lsp-result'>function run&lt;{&#13;    inference: string;&#13;}&gt;(thunk: (t: {&#13;    inference: string;&#13;}) =&gt; void): {&#13;    inference: string;&#13;}</span></span><span class='lsp'>o <span class='lsp-result'>(parameter) o: {&#13;    inference: string;&#13;}</span></span></span><span style=\"color: #0000FF\">=></span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">  <span class='lsp'>o.<span class='lsp-result'>(parameter) o: {&#13;    inference: string;&#13;}</span></span><span class='lsp'>inference <span class='lsp-result'>(property) inference: string</span></span>= </span><span style=\"color: #A31515\">\"INSERT STATE HERE\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">});</span></code></div></pre>\n<p>The type of <code>o</code> is determined to be <code>{ inference: string }</code> because</p>\n<ol>\n<li>Declaration initialisers are contextually typed by the\ndeclaration’s type: <code>{ inference: string }</code>.</li>\n<li>The return type of a call uses the contextual type for inferences,\nso the compiler infers that <code>T={ inference: string }</code>.</li>\n<li>Arrow functions use the contextual type to type their parameters,\nso the compiler gives <code>o: { inference: string }</code>.</li>\n</ol>\n<p>And it does so while you are typing, so that after typing <code>o.</code>, you\nget completions for the property <code>inference</code>, along with any other\nproperties you’d have in a real program.\nAltogether, this feature can make TypeScript’s inference look a bit\nlike a unifying type inference engine, but it is not.</p>\n<h2 id=\"type-aliases\" style=\"position:relative;\"><a href=\"#type-aliases\" aria-label=\"type aliases permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Type aliases</h2>\n<p>Type aliases are mere aliases, just like <code>type</code> in Haskell. The\ncompiler will attempt to use the alias name wherever it was used in\nthe source code, but does not always succeed.</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\"> <span class='lsp'>Size <span class='lsp-result'>type Size = [number, number]</span></span>= [number, number];</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> <span class='lsp'>x:<span class='lsp-result'>let x: Size</span></span> <span class='lsp'>Size <span class='lsp-result'>type Size = [number, number]</span></span>= [</span><span style=\"color: #09835A\">101.1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">999.9</span><span style=\"color: #000000\">];</span></code></div></pre>\n<p>The closest equivalent to <code>newtype</code> is a <em>tagged intersection</em>:</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\"> FString = string & { __compileTimeOnly: any };</span></code></div></pre>\n<p>An <code>FString</code> is just like a normal string, except that the compiler\nthinks it has a property named <code>__compileTimeOnly</code> that doesn’t\nactually exist. This means that <code>FString</code> can still be assigned to\n<code>string</code>, but not the other way round.</p>\n<h2 id=\"discriminated-unions\" style=\"position:relative;\"><a href=\"#discriminated-unions\" aria-label=\"discriminated 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>Discriminated Unions</h2>\n<p>The closest equivalent to <code>data</code> is a union of types with discriminant\nproperties, normally called discriminated unions in TypeScript:</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\"> Shape =</span>\n<span style=\"color: #000000\">  | { kind: </span><span style=\"color: #A31515\">\"circle\"</span><span style=\"color: #000000\">; radius: number }</span>\n<span style=\"color: #000000\">  | { kind: </span><span style=\"color: #A31515\">\"square\"</span><span style=\"color: #000000\">; x: number }</span>\n<span style=\"color: #000000\">  | { kind: </span><span style=\"color: #A31515\">\"triangle\"</span><span style=\"color: #000000\">; x: number; y: number };</span></code></div></pre>\n<p>Unlike Haskell, the tag, or discriminant, is just a property in each\nobject type. Each variant has an identical property with a different\nunit type. This is still a normal union type; the leading <code>|</code> is\nan optional part of the union type syntax. You can discriminate the\nmembers of the union using normal JavaScript code:</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\"> <span class='lsp'>Shape <span class='lsp-result'>type Shape = {&#13;    kind: &quot;circle&quot;;&#13;    radius: number;&#13;} | {&#13;    kind: &quot;square&quot;;&#13;    x: number;&#13;} | {&#13;    kind: &quot;triangle&quot;;&#13;    x: number;&#13;    y: number;&#13;}</span></span></span>\n<span style=\"color: #000000\">  | { <span class='lsp'>kind:<span class='lsp-result'>(property) kind: &quot;circle&quot;</span></span></span><span style=\"color: #A31515\">\"circle\"</span><span style=\"color: #000000\">; <span class='lsp'>radius:<span class='lsp-result'>(property) radius: number</span></span> number }</span>\n<span style=\"color: #000000\">  | { <span class='lsp'>kind:<span class='lsp-result'>(property) kind: &quot;square&quot;</span></span></span><span style=\"color: #A31515\">\"square\"</span><span style=\"color: #000000\">; <span class='lsp'>x:<span class='lsp-result'>(property) x: number</span></span> number }</span>\n<span style=\"color: #000000\">  | { <span class='lsp'>kind:<span class='lsp-result'>(property) kind: &quot;triangle&quot;</span></span></span><span style=\"color: #A31515\">\"triangle\"</span><span style=\"color: #000000\">; <span class='lsp'>x:<span class='lsp-result'>(property) x: number</span></span> number; <span class='lsp'>y:<span class='lsp-result'>(property) y: number</span></span> number };</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> <span class='lsp'>area(<span class='lsp-result'>function area(s: Shape): number</span></span><span class='lsp'>s:<span class='lsp-result'>(parameter) s: Shape</span></span> <span class='lsp'>Shape)<span class='lsp-result'>type Shape = {&#13;    kind: &quot;circle&quot;;&#13;    radius: number;&#13;} | {&#13;    kind: &quot;square&quot;;&#13;    x: number;&#13;} | {&#13;    kind: &quot;triangle&quot;;&#13;    x: number;&#13;    y: number;&#13;}</span></span> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (<span class='lsp'>s.<span class='lsp-result'>(parameter) s: Shape</span></span><span class='lsp'>kind <span class='lsp-result'>(property) kind: &quot;circle&quot; | &quot;square&quot; | &quot;triangle&quot;</span></span>=== </span><span style=\"color: #A31515\">\"circle\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <span class='lsp'>Math.<span class='lsp-result'>var Math: Math</span></span><span class='lsp'>PI <span class='lsp-result'>(property) Math.PI: number</span></span>* <span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;circle&quot;;&#13;    radius: number;&#13;}</span></span><span class='lsp'>radius <span class='lsp-result'>(property) radius: number</span></span>* <span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;circle&quot;;&#13;    radius: number;&#13;}</span></span><span class='lsp'>radius;<span class='lsp-result'>(property) radius: number</span></span></span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (<span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;square&quot;;&#13;    x: number;&#13;} | {&#13;    kind: &quot;triangle&quot;;&#13;    x: number;&#13;    y: number;&#13;}</span></span><span class='lsp'>kind <span class='lsp-result'>(property) kind: &quot;square&quot; | &quot;triangle&quot;</span></span>=== </span><span style=\"color: #A31515\">\"square\"</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> <span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;square&quot;;&#13;    x: number;&#13;}</span></span><span class='lsp'>x <span class='lsp-result'>(property) x: number</span></span>* <span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;square&quot;;&#13;    x: number;&#13;}</span></span><span class='lsp'>x;<span class='lsp-result'>(property) x: number</span></span></span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> (<span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;triangle&quot;;&#13;    x: number;&#13;    y: number;&#13;}</span></span><span class='lsp'>x <span class='lsp-result'>(property) x: number</span></span>* <span class='lsp'>s.<span class='lsp-result'>(parameter) s: {&#13;    kind: &quot;triangle&quot;;&#13;    x: number;&#13;    y: number;&#13;}</span></span><span class='lsp'>y)<span class='lsp-result'>(property) y: number</span></span> / </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Note that the return type is <code>area</code> is inferred to be <code>number</code> because\nTypeScript knows the function is total. If some variant is not\ncovered, the return type of <code>area</code> will be <code>number | undefined</code> instead.</p>\n<p>Also unlike Haskell, common properties show up in any union, so you\ncan usefully discriminate multiple members of the union:</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\"> height(s: Shape) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (s.kind === </span><span style=\"color: #A31515\">\"circle\"</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: #09835A\">2</span><span style=\"color: #000000\"> * s.radius;</span>\n<span style=\"color: #000000\">  } </span><span style=\"color: #0000FF\">else</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// s.kind: \"square\" | \"triangle\"</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> s.x;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h2 id=\"type-parameters\" style=\"position:relative;\"><a href=\"#type-parameters\" aria-label=\"type parameters permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Type Parameters</h2>\n<p>Like most C-descended languages, TypeScript requires declaration of\ntype parameters:</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\"> liftArray&lt;T&gt;(t: T): Array&lt;T&gt; {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> [t];</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>There is no case requirement, but type parameters are conventionally\nsingle uppercase letters. Type parameters can also be constrained to a\ntype, which behaves a bit like type class constraints:</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\"> firstish&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> { length: number }&gt;(t1: T, t2: T): T {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> t1.length &gt; t2.length ? t1 : t2;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>TypeScript can usually infer type arguments from a call based on the\ntype of the arguments, so type arguments are usually not needed.</p>\n<p>Because TypeScript is structural, it doesn’t need type parameters as\nmuch as nominal systems. Specifically, they are not needed to make a\nfunction polymorphic. Type parameters should only be used to\n<em>propagate</em> type information, such as constraining parameters to be\nthe same type:</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\"> length&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> ArrayLike&lt;unknown&gt;&gt;(t: T): number {}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> length(t: ArrayLike&lt;unknown&gt;): number {}</span></code></div></pre>\n<p>In the first <code>length</code>, T is not necessary; notice that it’s only\nreferenced once, so it’s not being used to constrain the type of the\nreturn value or other parameters.</p>\n<h3 id=\"higher-kinded-types\" style=\"position:relative;\"><a href=\"#higher-kinded-types\" aria-label=\"higher kinded 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>Higher-kinded types</h3>\n<p>TypeScript does not have higher kinded types, so the following is not legal:</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\"> length&lt;T </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> ArrayLike&lt;unknown&gt;, U&gt;(m: T&lt;U&gt;) {}</span></code></div></pre>\n<h3 id=\"point-free-programming\" style=\"position:relative;\"><a href=\"#point-free-programming\" aria-label=\"point free programming 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>Point-free programming</h3>\n<p>Point-free programming — heavy use of currying and function\ncomposition — is possible in JavaScript, but can be verbose.\nIn TypeScript, type inference often fails for point-free programs, so\nyou’ll end up specifying type parameters instead of value parameters. The\nresult is so verbose that it’s usually better to avoid point-free\nprogramming.</p>\n<h2 id=\"module-system\" style=\"position:relative;\"><a href=\"#module-system\" aria-label=\"module system 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>Module system</h2>\n<p>JavaScript’s modern module syntax is a bit like Haskell’s, except that\nany file with <code>import</code> or <code>export</code> is implicitly a module:</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\"> { value, Type } </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"npm-package\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">import</span><span style=\"color: #000000\"> { other, Types } </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"./local-package\"</span><span style=\"color: #000000\">;</span>\n<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\"> prefix </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"../lib/third-package\"</span><span style=\"color: #000000\">;</span></code></div></pre>\n<p>You can also import commonjs modules — modules written using node.js’\nmodule system:</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\"> f = </span><span style=\"color: #0000FF\">require</span><span style=\"color: #000000\">(</span><span style=\"color: #A31515\">\"single-function-package\"</span><span style=\"color: #000000\">);</span></code></div></pre>\n<p>You can export with an export list:</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\"> { f };</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> g();</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> g() {} </span><span style=\"color: #008000\">// g is not exported</span></code></div></pre>\n<p>Or by marking each export individually:</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\">function</span><span style=\"color: #000000\"> f { </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> g() }</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> g() { }</span></code></div></pre>\n<p>The latter style is more common but both are allowed, even in the same\nfile.</p>\n<h2 id=\"readonly-and-const\" style=\"position:relative;\"><a href=\"#readonly-and-const\" aria-label=\"readonly and const permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>readonly</code> and <code>const</code></h2>\n<p>In JavaScript, mutability is the default, although it allows variable\ndeclarations with <code>const</code> to declare that the <em>reference</em> is\nimmutable. The referent is still mutable:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> a = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">a.push(</span><span style=\"color: #09835A\">102</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// ):</span>\n<span style=\"color: #000000\">a[</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">] = </span><span style=\"color: #09835A\">101</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// D:</span></code></div></pre>\n<p>TypeScript additionally has a <code>readonly</code> modifier for properties.</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\"> Rx {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">readonly</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\"> rx: Rx = { x: </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> };</span>\n<span style=\"color: #000000\">rx.x = </span><span style=\"color: #09835A\">12</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<p>It also ships with a mapped type <code>Readonly&#x3C;T></code> that makes\nall properties <code>readonly</code>:</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\"> X {</span>\n<span style=\"color: #000000\">  x: number;</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> rx: Readonly&lt;X&gt; = { x: </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> };</span>\n<span style=\"color: #000000\">rx.x = </span><span style=\"color: #09835A\">12</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<p>And it has a specific <code>ReadonlyArray&#x3C;T></code> type that removes\nside-affecting methods and prevents writing to indices of the array,\nas well as special syntax for this type:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a: ReadonlyArray&lt;number&gt; = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> b: readonly number[] = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">a.push(</span><span style=\"color: #09835A\">102</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// error</span>\n<span style=\"color: #000000\">b[</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">] = </span><span style=\"color: #09835A\">101</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<p>You can also use a const-assertion, which operates on arrays and\nobject literals:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">] </span><span style=\"color: #0000FF\">as</span><span style=\"color: #000000\"> const;</span>\n<span style=\"color: #000000\">a.push(</span><span style=\"color: #09835A\">102</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// error</span>\n<span style=\"color: #000000\">a[</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">] = </span><span style=\"color: #09835A\">101</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<p>However, none of these options are the default, so they are not\nconsistently used in TypeScript code.</p>","headings":[{"value":"Prerequisites","depth":1},{"value":"Concepts not in Haskell","depth":1},{"value":"Built-in types","depth":2},{"value":"Other important Typescript types","depth":3},{"value":"Boxed types","depth":3},{"value":"Gradual typing","depth":2},{"value":"Structural typing","depth":2},{"value":"Unions","depth":2},{"value":"Intersections","depth":3},{"value":"Unit types","depth":2},{"value":"Concepts similar to Haskell","depth":1},{"value":"Contextual typing","depth":2},{"value":"Type aliases","depth":2},{"value":"Discriminated Unions","depth":2},{"value":"Type Parameters","depth":2},{"value":"Higher-kinded types","depth":3},{"value":"Point-free programming","depth":3},{"value":"Module system","depth":2},{"value":"readonly and const","depth":2}],"frontmatter":{"permalink":"/docs/handbook/typescript-in-5-minutes-func.html","title":"TypeScript for Functional Programmers"}}},"pageContext":{"slug":"/docs/handbook/typescript-in-5-minutes-func.html","isOldHandbook":true}}}