{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/jsx.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":"57a512bc-aad8-53b0-a8f8-0718e9c4f537","excerpt":"Introduction JSX is an embeddable XML-like syntax.\nIt is meant to be transformed into valid JavaScript, though the semantics of that transformation are…","html":"<h1 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction 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>Introduction</h1>\n<p><a href=\"https://facebook.github.io/jsx/\">JSX</a> is an embeddable XML-like syntax.\nIt is meant to be transformed into valid JavaScript, though the semantics of that transformation are implementation-specific.\nJSX rose to popularity with the <a href=\"https://reactjs.org/\">React</a> framework, but has since seen other implementations as well.\nTypeScript supports embedding, type checking, and compiling JSX directly to JavaScript.</p>\n<h1 id=\"basic-usage\" style=\"position:relative;\"><a href=\"#basic-usage\" aria-label=\"basic usage 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>Basic usage</h1>\n<p>In order to use JSX you must do two things.</p>\n<ol>\n<li>Name your files with a <code>.tsx</code> extension</li>\n<li>Enable the <code>jsx</code> option</li>\n</ol>\n<p>TypeScript ships with three JSX modes: <code>preserve</code>, <code>react</code>, and <code>react-native</code>.\nThese modes only affect the emit stage - type checking is unaffected.\nThe <code>preserve</code> mode will keep the JSX as part of the output to be further consumed by another transform step (e.g. <a href=\"https://babeljs.io/\">Babel</a>).\nAdditionally the output will have a <code>.jsx</code> file extension.\nThe <code>react</code> mode will emit <code>React.createElement</code>, does not need to go through a JSX transformation before use, and the output will have a <code>.js</code> file extension.\nThe <code>react-native</code> mode is the equivalent of <code>preserve</code> in that it keeps all JSX, but the output will instead have a <code>.js</code> file extension.</p>\n<table>\n<thead>\n<tr>\n<th>Mode</th>\n<th>Input</th>\n<th>Output</th>\n<th>Output File Extension</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>preserve</code></td>\n<td><code>&#x3C;div /></code></td>\n<td><code>&#x3C;div /></code></td>\n<td><code>.jsx</code></td>\n</tr>\n<tr>\n<td><code>react</code></td>\n<td><code>&#x3C;div /></code></td>\n<td><code>React.createElement(\"div\")</code></td>\n<td><code>.js</code></td>\n</tr>\n<tr>\n<td><code>react-native</code></td>\n<td><code>&#x3C;div /></code></td>\n<td><code>&#x3C;div /></code></td>\n<td><code>.js</code></td>\n</tr>\n</tbody>\n</table>\n<p>You can specify this mode using either the <code>--jsx</code> command line flag or the corresponding option in your <a href=\"./tsconfig.json.md\">tsconfig.json</a> file.</p>\n<blockquote>\n<p>*Note: You can specify the JSX factory function to use when targeting react JSX emit with <code>--jsxFactory</code> option (defaults to <code>React.createElement</code>)</p>\n</blockquote>\n<h1 id=\"the-as-operator\" style=\"position:relative;\"><a href=\"#the-as-operator\" aria-label=\"the as operator 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>The <code>as</code> operator</h1>\n<p>Recall how to write a type assertion:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> foo = &lt;foo&gt;bar;</span></code></div></pre>\n<p>This asserts the variable <code>bar</code> to have the type <code>foo</code>.\nSince TypeScript also uses angle brackets for type assertions, combining it with JSX’s syntax would introduce certain parsing difficulties. As a result, TypeScript disallows angle bracket type assertions in <code>.tsx</code> files.</p>\n<p>Since the above syntax cannot be used in <code>.tsx</code> files, an alternate type assertion operator should be used: <code>as</code>.\nThe example can easily be rewritten with the <code>as</code> operator.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> foo = bar </span><span style=\"color: #0000FF\">as</span><span style=\"color: #000000\"> foo;</span></code></div></pre>\n<p>The <code>as</code> operator is available in both <code>.ts</code> and <code>.tsx</code> files, and is identical in behavior to the angle-bracket type assertion style.</p>\n<h1 id=\"type-checking\" style=\"position:relative;\"><a href=\"#type-checking\" aria-label=\"type checking permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Type Checking</h1>\n<p>In order to understand type checking with JSX, you must first understand the difference between intrinsic elements and value-based elements.\nGiven a JSX expression <code>&#x3C;expr /></code>, <code>expr</code> may either refer to something intrinsic to the environment (e.g. a <code>div</code> or <code>span</code> in a DOM environment) or to a custom component that you’ve created.\nThis is important for two reasons:</p>\n<ol>\n<li>For React, intrinsic elements are emitted as strings (<code>React.createElement(\"div\")</code>), whereas a component you’ve created is not (<code>React.createElement(MyComponent)</code>).</li>\n<li>The types of the attributes being passed in the JSX element should be looked up differently.\nIntrinsic element attributes should be known <em>intrinsically</em> whereas components will likely want to specify their own set of attributes.</li>\n</ol>\n<p>TypeScript uses the <a href=\"http://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components\">same convention that React does</a> for distinguishing between these.\nAn intrinsic element always begins with a lowercase letter, and a value-based element always begins with an uppercase letter.</p>\n<h2 id=\"intrinsic-elements\" style=\"position:relative;\"><a href=\"#intrinsic-elements\" aria-label=\"intrinsic elements 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>Intrinsic elements</h2>\n<p>Intrinsic elements are looked up on the special interface <code>JSX.IntrinsicElements</code>.\nBy default, if this interface is not specified, then anything goes and intrinsic elements will not be type checked.\nHowever, if this interface <em>is</em> present, then the name of the intrinsic element is looked up as a property on the <code>JSX.IntrinsicElements</code> interface.\nFor example:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> IntrinsicElements {</span>\n<span style=\"color: #000000\">    foo: any;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">&lt;foo /&gt;; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">&lt;bar /&gt;; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<p>In the above example, <code>&#x3C;foo /></code> will work fine but <code>&#x3C;bar /></code> will result in an error since it has not been specified on <code>JSX.IntrinsicElements</code>.</p>\n<blockquote>\n<p>Note: You can also specify a catch-all string indexer on <code>JSX.IntrinsicElements</code> as follows:</p>\n</blockquote>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> IntrinsicElements {</span>\n<span style=\"color: #000000\">    [elemName: string]: any;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h2 id=\"value-based-elements\" style=\"position:relative;\"><a href=\"#value-based-elements\" aria-label=\"value based elements 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>Value-based elements</h2>\n<p>Value-based elements are simply looked up by identifiers that are in scope.</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\"> MyComponent </span><span style=\"color: #0000FF\">from</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"./myComponent\"</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">&lt;MyComponent /&gt;; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">&lt;SomeOtherComponent /&gt;; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<p>There are two ways to define a value-based element:</p>\n<ol>\n<li>Function Component (FC)</li>\n<li>Class Component</li>\n</ol>\n<p>Because these two types of value-based elements are indistinguishable from each other in a JSX expression, first TS tries to resolve the expression as a Function Component using overload resolution. If the process succeeds, then TS finishes resolving the expression to its declaration. If the value fails to resolve as a Function Component, TS will then try to resolve it as a class component. If that fails, TS will report an error.</p>\n<h3 id=\"function-component\" style=\"position:relative;\"><a href=\"#function-component\" aria-label=\"function component 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>Function Component</h3>\n<p>As the name suggests, the component is defined as a JavaScript function where its first argument is a <code>props</code> object.\nTS enforces that its return type must be assignable to <code>JSX.Element</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\"> FooProp {</span>\n<span style=\"color: #000000\">  name: string;</span>\n<span style=\"color: #000000\">  X: number;</span>\n<span style=\"color: #000000\">  Y: number;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> AnotherComponent(prop: {name: string});</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> ComponentFoo(prop: FooProp) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> &lt;AnotherComponent name={prop.name} /&gt;;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> Button = (prop: {value: string}, context: { color: string }) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> &lt;button&gt;</span></code></div></pre>\n<p>Because a Function Component is simply a JavaScript function, function overloads may be used here as well:</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\"> ClickableProps {</span>\n<span style=\"color: #000000\">  children: JSX.Element[] | JSX.Element</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> HomeProps </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> ClickableProps {</span>\n<span style=\"color: #000000\">  home: JSX.Element;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> SideProps </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> ClickableProps {</span>\n<span style=\"color: #000000\">  side: JSX.Element | string;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> MainButton(prop: HomeProps): JSX.Element;</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> MainButton(prop: SideProps): JSX.Element {</span>\n<span style=\"color: #000000\">  ...</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<blockquote>\n<p>Note: Function Components were formerly known as Stateless Function Components (SFC). As Function Components can no longer be considered stateless in recent versions of react, the type <code>SFC</code> and its alias <code>StatelessComponent</code> were deprecated.</p>\n</blockquote>\n<h3 id=\"class-component\" style=\"position:relative;\"><a href=\"#class-component\" aria-label=\"class component 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>Class Component</h3>\n<p>It is possible to define the type of a class component.\nHowever, to do so it is best to understand two new terms: the <em>element class type</em> and the <em>element instance type</em>.</p>\n<p>Given <code>&#x3C;Expr /></code>, the <em>element class type</em> is the type of <code>Expr</code>.\nSo in the example above, if <code>MyComponent</code> was an ES6 class the class type would be that class’s constructor and statics.\nIf <code>MyComponent</code> was a factory function, the class type would be that function.</p>\n<p>Once the class type is established, the instance type is determined by the union of the return types of the class type’s construct or call signatures (whichever is present).\nSo again, in the case of an ES6 class, the instance type would be the type of an instance of that class, and in the case of a factory function, it would be the type of the value returned from the function.</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\"> MyComponent {</span>\n<span style=\"color: #000000\">  render() {}</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// use a construct signature</span>\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> myComponent = </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> MyComponent();</span>\n\n<span style=\"color: #008000\">// element class type =&gt; MyComponent</span>\n<span style=\"color: #008000\">// element instance type =&gt; { render: () =&gt; void }</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> MyFactoryFunction() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">    render: () </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> {}</span>\n<span style=\"color: #000000\">  };</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// use a call signature</span>\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> myComponent = MyFactoryFunction();</span>\n\n<span style=\"color: #008000\">// element class type =&gt; FactoryFunction</span>\n<span style=\"color: #008000\">// element instance type =&gt; { render: () =&gt; void }</span></code></div></pre>\n<p>The element instance type is interesting because it must be assignable to <code>JSX.ElementClass</code> or it will result in an error.\nBy default <code>JSX.ElementClass</code> is <code>{}</code>, but it can be augmented to limit the use of JSX to only those types that conform to the proper interface.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> ElementClass {</span>\n<span style=\"color: #000000\">    render: any;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> MyComponent {</span>\n<span style=\"color: #000000\">  render() {}</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> MyFactoryFunction() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> { render: () </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> {} };</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">&lt;MyComponent /&gt;; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">&lt;MyFactoryFunction /&gt;; </span><span style=\"color: #008000\">// ok</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> NotAValidComponent {}</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> NotAValidFactoryFunction() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> {};</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">&lt;NotAValidComponent /&gt;; </span><span style=\"color: #008000\">// error</span>\n<span style=\"color: #000000\">&lt;NotAValidFactoryFunction /&gt;; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<h2 id=\"attribute-type-checking\" style=\"position:relative;\"><a href=\"#attribute-type-checking\" aria-label=\"attribute type checking permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute type checking</h2>\n<p>The first step to type checking attributes is to determine the <em>element attributes type</em>.\nThis is slightly different between intrinsic and value-based elements.</p>\n<p>For intrinsic elements, it is the type of the property on <code>JSX.IntrinsicElements</code></p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> IntrinsicElements {</span>\n<span style=\"color: #000000\">    foo: { bar?: boolean };</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// element attributes type for 'foo' is '{bar?: boolean}'</span>\n<span style=\"color: #000000\">&lt;foo bar /&gt;;</span></code></div></pre>\n<p>For value-based elements, it is a bit more complex.\nIt is determined by the type of a property on the <em>element instance type</em> that was previously determined.\nWhich property to use is determined by <code>JSX.ElementAttributesProperty</code>.\nIt should be declared with a single property.\nThe name of that property is then used.\nAs of TypeScript 2.8, if <code>JSX.ElementAttributesProperty</code> is not provided, the type of first parameter of the class element’s constructor or Function Component’s call will be used instead.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> ElementAttributesProperty {</span>\n<span style=\"color: #000000\">    props; </span><span style=\"color: #008000\">// specify the property name to use</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> MyComponent {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// specify the property on the element instance type</span>\n<span style=\"color: #000000\">  props: {</span>\n<span style=\"color: #000000\">    foo?: string;</span>\n<span style=\"color: #000000\">  };</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// element attributes type for 'MyComponent' is '{foo?: string}'</span>\n<span style=\"color: #000000\">&lt;MyComponent foo=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\"> /&gt;;</span></code></div></pre>\n<p>The element attribute type is used to type check the attributes in the JSX.\nOptional and required properties are supported.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> IntrinsicElements {</span>\n<span style=\"color: #000000\">    foo: { requiredProp: string; optionalProp?: number };</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">&lt;foo requiredProp=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\"> /&gt;; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">&lt;foo requiredProp=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\"> optionalProp={0} /&gt;; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">&lt;foo /&gt;; </span><span style=\"color: #008000\">// error, requiredProp is missing</span>\n<span style=\"color: #000000\">&lt;foo requiredProp={0} /&gt;; </span><span style=\"color: #008000\">// error, requiredProp should be a string</span>\n<span style=\"color: #000000\">&lt;foo requiredProp=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\"> unknownProp /&gt;; </span><span style=\"color: #008000\">// error, unknownProp does not exist</span>\n<span style=\"color: #000000\">&lt;foo requiredProp=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\"> some-unknown-prop /&gt;; </span><span style=\"color: #008000\">// ok, because 'some-unknown-prop' is not a valid identifier</span></code></div></pre>\n<blockquote>\n<p>Note: If an attribute name is not a valid JS identifier (like a <code>data-*</code> attribute), it is not considered to be an error if it is not found in the element attributes type.</p>\n</blockquote>\n<p>Additionally, the <code>JSX.IntrinsicAttributes</code> interface can be used to specify extra properties used by the JSX framework which are not generally used by the components’ props or arguments - for instance <code>key</code> in React. Specializing further, the generic <code>JSX.IntrinsicClassAttributes&#x3C;T></code> type may also be used to specify the same kind of extra attributes just for class components (and not Function Components). In this type, the generic parameter corresponds to the class instance type. In React, this is used to allow the <code>ref</code> attribute of type <code>Ref&#x3C;T></code>. Generally speaking, all of the properties on these interfaces should be optional, unless you intend that users of your JSX framework need to provide some attribute on every tag.</p>\n<p>The spread operator also works:</p>\n<pre><code class=\"language-JSX\">var props = { requiredProp: \"bar\" };\n&#x3C;foo {...props} />; // ok\n\nvar badProps = {};\n&#x3C;foo {...badProps} />; // error\n</code></pre>\n<h2 id=\"children-type-checking\" style=\"position:relative;\"><a href=\"#children-type-checking\" aria-label=\"children type checking permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Children Type Checking</h2>\n<p>In TypeScript 2.3, TS introduced type checking of <em>children</em>. <em>children</em> is a special property in an <em>element attributes type</em> where child <em>JSXExpression</em>s are taken to be inserted into the attributes.\nSimilar to how TS uses <code>JSX.ElementAttributesProperty</code> to determine the name of <em>props</em>, TS uses <code>JSX.ElementChildrenAttribute</code> to determine the name of <em>children</em> within those props.\n<code>JSX.ElementChildrenAttribute</code> should be declared with a single property.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">namespace</span><span style=\"color: #000000\"> JSX {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> ElementChildrenAttribute {</span>\n<span style=\"color: #000000\">    children: {}; </span><span style=\"color: #008000\">// specify children name to use</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">&lt;div&gt;</span>\n<span style=\"color: #000000\">  &lt;h1&gt;Hello&lt;/h1&gt;</span>\n<span style=\"color: #000000\">&lt;/div&gt;;</span>\n\n<span style=\"color: #000000\">&lt;div&gt;</span>\n<span style=\"color: #000000\">  &lt;h1&gt;Hello&lt;/h1&gt;</span>\n<span style=\"color: #000000\">  World</span>\n<span style=\"color: #000000\">&lt;/div&gt;;</span>\n\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> CustomComp = (props) </span><span style=\"color: #0000FF\">=&gt;</span><span style=\"color: #000000\"> &lt;div&gt;{props.children}&lt;/div&gt;</span>\n<span style=\"color: #000000\">&lt;CustomComp&gt;</span>\n<span style=\"color: #000000\">  &lt;div&gt;Hello World&lt;/div&gt;</span>\n<span style=\"color: #000000\">  {</span><span style=\"color: #A31515\">\"This is just a JS expression...\"</span><span style=\"color: #000000\"> + </span><span style=\"color: #09835A\">1000</span><span style=\"color: #000000\">}</span>\n<span style=\"color: #000000\">&lt;/CustomComp&gt;</span></code></div></pre>\n<p>You can specify the type of <em>children</em> like any other attribute. This will override the default type from, eg the <a href=\"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react\">React typings</a> if you use them.</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\"> PropsType {</span>\n<span style=\"color: #000000\">  children: JSX.Element</span>\n<span style=\"color: #000000\">  name: string</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> Component </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> React.Component&lt;PropsType, {}&gt; {</span>\n<span style=\"color: #000000\">  render() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> (</span>\n<span style=\"color: #000000\">      &lt;h2&gt;</span>\n<span style=\"color: #000000\">        {this.props.children}</span>\n<span style=\"color: #000000\">      &lt;/h2&gt;</span>\n<span style=\"color: #000000\">    )</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// OK</span>\n<span style=\"color: #000000\">&lt;Component name=</span><span style=\"color: #A31515\">\"foo\"</span><span style=\"color: #000000\">&gt;</span>\n<span style=\"color: #000000\">  &lt;h1&gt;Hello World&lt;/h1&gt;</span>\n<span style=\"color: #000000\">&lt;/Component&gt;</span>\n\n<span style=\"color: #008000\">// Error: children is of type JSX.Element not array of JSX.Element</span>\n<span style=\"color: #000000\">&lt;Component name=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\">&gt;</span>\n<span style=\"color: #000000\">  &lt;h1&gt;Hello World&lt;/h1&gt;</span>\n<span style=\"color: #000000\">  &lt;h2&gt;Hello World&lt;/h2&gt;</span>\n<span style=\"color: #000000\">&lt;/Component&gt;</span>\n\n<span style=\"color: #008000\">// Error: children is of type JSX.Element not array of JSX.Element or string.</span>\n<span style=\"color: #000000\">&lt;Component name=</span><span style=\"color: #A31515\">\"baz\"</span><span style=\"color: #000000\">&gt;</span>\n<span style=\"color: #000000\">  &lt;h1&gt;Hello&lt;/h1&gt;</span>\n<span style=\"color: #000000\">  World</span>\n<span style=\"color: #000000\">&lt;/Component&gt;</span></code></div></pre>\n<h1 id=\"the-jsx-result-type\" style=\"position:relative;\"><a href=\"#the-jsx-result-type\" aria-label=\"the jsx result type 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>The JSX result type</h1>\n<p>By default the result of a JSX expression is typed as <code>any</code>.\nYou can customize the type by specifying the <code>JSX.Element</code> interface.\nHowever, it is not possible to retrieve type information about the element, attributes or children of the JSX from this interface.\nIt is a black box.</p>\n<h1 id=\"embedding-expressions\" style=\"position:relative;\"><a href=\"#embedding-expressions\" aria-label=\"embedding expressions 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>Embedding Expressions</h1>\n<p>JSX allows you to embed expressions between tags by surrounding the expressions with curly braces (<code>{ }</code>).</p>\n<pre><code class=\"language-JSX\">var a = &#x3C;div>\n  {[\"foo\", \"bar\"].map(i => &#x3C;span>{i / 2}&#x3C;/span>)}\n&#x3C;/div>\n</code></pre>\n<p>The above code will result in an error since you cannot divide a string by a number.\nThe output, when using the <code>preserve</code> option, looks like:</p>\n<pre><code class=\"language-JSX\">var a = &#x3C;div>\n  {[\"foo\", \"bar\"].map(function (i) { return &#x3C;span>{i / 2}&#x3C;/span>; })}\n&#x3C;/div>\n</code></pre>\n<h1 id=\"react-integration\" style=\"position:relative;\"><a href=\"#react-integration\" aria-label=\"react integration 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>React integration</h1>\n<p>To use JSX with React you should use the <a href=\"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react\">React typings</a>.\nThese typings define the <code>JSX</code> namespace appropriately for use with React.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">/// </span><span style=\"color: #800000\">&lt;reference</span><span style=\"color: #008000\"> </span><span style=\"color: #DC0000\">path</span><span style=\"color: #000000\">=</span><span style=\"color: #A31515\">\"react.d.ts\"</span><span style=\"color: #008000\"> </span><span style=\"color: #800000\">/&gt;</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Props {</span>\n<span style=\"color: #000000\">  foo: string;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> MyComponent </span><span style=\"color: #0000FF\">extends</span><span style=\"color: #000000\"> React.Component&lt;Props, {}&gt; {</span>\n<span style=\"color: #000000\">  render() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> &lt;span&gt;{</span><span style=\"color: #0000FF\">this</span><span style=\"color: #000000\">.props.foo}&lt;/span&gt;;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">&lt;MyComponent foo=</span><span style=\"color: #A31515\">\"bar\"</span><span style=\"color: #000000\"> /&gt;; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">&lt;MyComponent foo={0} /&gt;; </span><span style=\"color: #008000\">// error</span></code></div></pre>\n<h1 id=\"factory-functions\" style=\"position:relative;\"><a href=\"#factory-functions\" aria-label=\"factory functions 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>Factory Functions</h1>\n<p>The exact factory function used by the <code>jsx: react</code> compiler option is configurable. It may be set using either the <code>jsxFactory</code> command line option, or an inline <code>@jsx</code> comment pragma to set it on a per-file basis. For example, if you set <code>jsxFactory</code> to <code>createElement</code>, <code>&#x3C;div /></code> will emit as <code>createElement(\"div\")</code> instead of <code>React.createElement(\"div\")</code>.</p>\n<p>The comment pragma version may be used like so (in TypeScript 2.8):</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\"> preact = </span><span style=\"color: #0000FF\">require</span><span style=\"color: #000000\">(</span><span style=\"color: #A31515\">\"preact\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #008000\">/* @jsx preact.h */</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> x = &lt;div /&gt;;</span></code></div></pre>\n<p>emits as:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> preact = require(</span><span style=\"color: #A31515\">\"preact\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> x = preact.h(</span><span style=\"color: #A31515\">\"div\"</span><span style=\"color: #000000\">, </span><span style=\"color: #0000FF\">null</span><span style=\"color: #000000\">);</span></code></div></pre>\n<p>The factory chosen will also affect where the <code>JSX</code> namespace is looked up (for type checking information) before falling back to the global one. If the factory is defined as <code>React.createElement</code> (the default), the compiler will check for <code>React.JSX</code> before checking for a global <code>JSX</code>. If the factory is defined as <code>h</code>, it will check for <code>h.JSX</code> before a global <code>JSX</code>.</p>","headings":[{"value":"Introduction","depth":1},{"value":"Basic usage","depth":1},{"value":"The as operator","depth":1},{"value":"Type Checking","depth":1},{"value":"Intrinsic elements","depth":2},{"value":"Value-based elements","depth":2},{"value":"Function Component","depth":3},{"value":"Class Component","depth":3},{"value":"Attribute type checking","depth":2},{"value":"Children Type Checking","depth":2},{"value":"The JSX result type","depth":1},{"value":"Embedding Expressions","depth":1},{"value":"React integration","depth":1},{"value":"Factory Functions","depth":1}],"frontmatter":{"permalink":"/docs/handbook/jsx.html","title":"JSX"}}},"pageContext":{"slug":"/docs/handbook/jsx.html","isOldHandbook":true}}}