JSX

JSX 是一种可嵌入的类 XML 语法。它旨在转换为有效的 JavaScript,尽管该转换的语义是特定于实现的。JSX 随着 React 框架而流行起来,但后来也看到了其他实现。TypeScript 支持嵌入、类型检查和将 JSX 直接编译为 JavaScript。

基本用法

为了使用 JSX,你必须做两件事。

  1. 使用 .tsx 扩展名命名您的文件
  2. 启用 jsx 选项

TypeScript 附带三种 JSX 模式:preservereactreact-native。这些模式只影响触发阶段——类型检查不受影响。preserve 模式将保持 JSX 作为输出的一部分,以供另一个转换步骤(例如 Babel)进一步使用。此外,输出将具有 .jsx 文件扩展名。react 模式会发出 React.createElement,使用前不需要经过 JSX 转换,输出会有 .js 文件扩展名。react-native 模式等价于 preserve,因为它保留所有 JSX,但输出将改为具有 .js 文件扩展名。

模式输入输出输出文件扩展名
preserve<div /><div />.jsx
react<div />React.createElement("div").js
react-native<div /><div />.js
react-jsx<div />_jsx("div", {}, void 0);.js
react-jsxdev<div />_jsxDEV("div", {}, void 0, false, {...}, this);.js

您可以使用 jsx 命令行标志或相应的选项 tsconfig.json 中的 jsx 文件指定此模式。

*注意:您可以使用 jsxFactory 选项指定 JSX 工厂函数(默认为 React.createElement

as 运算符

r/kHAo2DkSaauqEnTSSkXPgzvHIIi6eiXdkd2iWJ8aP4M6czzGlN180Hh++xqOEN

const foo = <foo>bar;

kHGa35NYeGDVs4SICcLzb7NmVnAm4CeT7nsbMvJrLnx9a8GiKoQSxcjps1MIP3gpytrtR+WGg2tj3minY2KvLXxioaoiZThbJHucEonvaq1osimEfd1dX9cnUZlYz3w23m7wunCNVtvJhMMEzeiZKsAdu17C5Egz7mD2pm4ofEhK3eNuxz+6/PE/y5tG5FQXNJo06svfBkGR83fXss2D1StL52GI0kScu8hp6SLwX63y5oFc/lATJjlWkMKCh3ZUSWn6BjJqFvyRfi70q7EPW9B0ae4XIv1GDcF60jHaLgOkrRghvbSIxhyi6QfG0A/LPQd/1mtNpFcNR+fs88q0X/ZWNyKJIbYGrGj6hIe6BNndCuR3P+7a1+hRyCCSyksgCIqf9rIZ3sV/ED1xrLXCCA==

+EHt7GwXZFY9bce5bAZKhGRcOrGp2xPlJCqVFZJOdmSmi+nogTBxKA6dIkF3H0an1FV+SMK7gtLB5YYYbQtbK6OGDXozQY7dPLd7phQj8bIHaSqz7gVVSikeGHlaLBVPN2pLApUhZbhgr0OVBj7mL7tJNPPXK9LcFlvKOjGYYDuJAxefpmdyN5w2nF4ottZzPRbIa0oP+7wZtRJ6kLz2Uy2JixjcW0G+88JcK7nYaQsoT4Y4YlZS06clBc5tWUvYbGAruLQdavscyXKtRpmqPQ==

const foo = bar as foo;

SMdIvrUpMSqph5rPe4wdPVCB/BFngSGKdRR5vkP488rrAsohM+AcoeNmIPJ+olPX7yh3LiFOI9Amogt7mrb9SzVA1CdBL4jFa/GbGDp0ev0HTmbhxjelGEv8Yx4OrDTMexI3f4cO1VgbDUdxBNzcaRHWcJUDpDlhuDLEubDJBXX7UTI7qKe6nUchoBay59QlSNmFAKIE9tDC8z/C9wKTcw==

类型检查

tVh7FQ0+43mzjWKtTP/q7OJFEfm7LwxxgT4l+kYJUw0X9qZREatkFEkxOQEQk+nsHRhod3MwTZfWSPPOh6VN1aNgLXbQH3CYuKuPIN9N2G4wKEvCdosMybbu03ipCNQyCB8J12zlGnpcAvB7J3SD0D16SEz+u96P8EnUauqeWgXCxDikFPbKAZi0gKf/F4osaCsuzpHCSbDvm+hL1kdYtQwoiZoqru79isXZ1Y/tBG0rKTttQffh+4vjTwzTIxAqz2HAsQ57749ilYCA5bJseX0fuOw5tXPfSkJwshXvsY8UABw9QoIJMu5efMRoMj6G9ubGHVHjCjVx2xRXgQiQrHDaqIeGv7nhD0qWYlDy9MQi4YuYWQu8hEPZiONH59ta/hgOHKs4TrwZWCXt0WI8fh8+RqD614mwpTZW3VhejmliraOR0e6GJlxuJQxqWLrBZ/dteolEDZYMkrlsioNV/krtEHDc6CWlNUrIuNpAuVU=

  1. 对于 React,内在元素作为字符串 (React.createElement("div")) 发出,而您创建的组件不是 (React.createElement(MyComponent))。
  2. 在 JSX 元素中传递的属性类型应该以不同的方式查找。内在元素属性应该是内在已知的,而组件可能希望指定它们自己的属性集。

qA/18rbJULzL957nivopyEB36kKVvaf8j7Azit3skijpQNJsNZkEYJBvjnWfj7cD1bYjj9JkYV2hAnHEC/jaI6aMDXfhS9q7S5c47CekWlN8MOaiUq7z0GTP1mDSQU7o9nLo0JwPG5vkhcyuwnQwVcGeDdajB7Y8KZxYsByQLdR1ModaKLCEu++DT8k4xdB1vx3R9lbhdkeslESWKU/SA+EIHTRS+Ed/KvwigjIwX6ZnoHVjuNutw8B5ppKyEz9V0L3MexAOsEaChZ2Kgd00JA==

内在要素

8Nfa8fykKn4LjGjIf4zd0kbDg/V37lNDssHHW7Pbayl5doGkK1oGl2+NTVYPEmYY3K0bzP0DPvurtdjprXrnuUo0Y4aYSLcK4xWrDnXksuzebJLuJbpGxyarOExaTyTVCmfxyoox/1NfHvgZ6MzEViyzU9Rfvw1a04xCP8JDdGpB/ET82Dfi2DmWgN6nj7kJAA0zm2z6LAg50ZygUaS8eFnjVthziAS3jXNGZ5thDxZIsvXZmvloak28rhy3s799nbRuVOUwioaqjRGNMy0uT6BxemOkrRhXFzeq5NEX4nLa1MOlObSZYYZvggyiWKx8i1/l6PAeqxq/RJLH9T/IchQ+Ahp0cb2q8qL4lsdUpfJdQb3EZIZiEc8bKJfg4TE4uAjwc+b0kItTFWmavni63gYki7MYs5GFr6f4r6HP7OXoRI364IYxcNFIUtWNB34lE14X8ExKPhhuOmGnFAkJYA==

declare namespace JSX {
  interface IntrinsicElements {
    foo: any;
  }
}

<foo />; // ok
<bar />; // error

rm09P19uFA/oRP6Y11xWwMkHtj4RqYvMHLfaU8vVGMdkX4RMSoZdlR1ybVXtn/7c6xAx5yaTGfnMGakgyY5gA+rNlSxWhyaJxMH8FV0Rc5EK9e1M1j0c50MIq/mFzgAjasGRvnVAsgj4YTFSc4h6zqlK3Vq51e+MXCo3BFM3ODNXD2/er3lLECRZmQsLh8u26Xjf24jFL/aKVv+HMF8k3Rauue3qb9k61qh4UNhEfQOD7rPmEj4WrBT4K6/go1Fd

y90nYp5e8K6uZX1IaH/X4VYt6ZQvmABRTVg8V4XKgLh+idhT/S5VaTCKpPpcM89Fvcczb1ie5kYIpa0pcpg69CVwDmXehHLMrem+yN4AuuOrzizKGmd+pcceQpgwpmV1RLWQ5L6PDPJeGRdg2hYcHrBi3yKGA9R0RBYFR3clk6M=

declare namespace JSX {
  interface IntrinsicElements {
    [elemName: string]: any;
  }
}

基于值的元素

QSWPEV6lRU+rn+jVu+913ef79Ux58xxdQfFTtQK6feaij7O8F2cPb+BGOk89ygNwXjNE7We/fyiZsBFTqxc0RhmPZ1fxSOW85Q54cSTGLZc=

import MyComponent from "./myComponent";

<MyComponent />; // ok
<SomeOtherComponent />; // error

5yA4NrlKwHNLmScnDgkm+adLCfV3iEj3W0LjOvKjUeNcQID5hkHhQMtmOHsWk1eYf9IyKPjRs3JZk8DG+B2u6g==

  1. 功能组件 (FC)
  2. 类组件

0oQm1Fa+1lRZw9QXZVTypgli2+D2oRBmUMhJRVbdLfjpkNptDySxYIgK5cS32x7quuIP0J6ifHA4wviHTQDweu80dGrDFXfrJxnrc4odMFP431wO4HeWqMmzAM0gz79I3/KTtxAY9Vxh09wWiBUMHq4cJdg0pCoOz72IwmbS0Yn2R9U9PBAvXmkcoWHSyKCwkBlxeSYNKlvU4Xl0FYsXEJmAZzJj0Bfhr0BfUfBTpx/6gk8isaqa1SuLy23dxcGW3gqvwcSRQGCYPf/d6eLlkKpjtjdv20d/NGhruWscPuYBSL8+msbPyLNIvSkiISn/K4nIY1MdQj1tzqeLM0w4mMzHO2sQaXYa8EjmIUwYhfJVSw6+PTTfXQXHUEAdjm9bQjzz3zymyi2VhL+6PEVoRX0iB5TvKdEXfXoygkLec4kpsucPwAYrtovj3rT9DheYBQUlOW7T9FE9l0TmTPv2qQ==

函数组件

cR0LRHdezX6J30XkDsj7dHHU4NPdacbkWHRm25gdjH5RhIBL4/atJUMUOJeKsN79BkEWDK6sGNnqe9OBG50QDkIHnMSJpBzyOkKhnig0x5fJPfplwxnEuj+x6fzvRh/GB0eMCWapkkia/xFgc75pngNI6rkfRab2jmkfUNRa++KPyUrI0/B+SNv9TZakURkKsThSDaD4Tcj8kJ+0oMYlnByUZzsNoam/mn67Iq6CpeEYPmTUtZNpUYGA2d30FHU0

interface FooProp {
  name: string;
  X: number;
  Y: number;
}

declare function AnotherComponent(prop: { name: string });
function ComponentFoo(prop: FooProp) {
  return <AnotherComponent name={prop.name} />;
}

const Button = (prop: { value: string }, context: { color: string }) => (
  <button />
);

KwW6TA/4eHVuCRhrV/xNONMYkxYOJl5pe3Om5x9ZEZ9m8r9JMgaE0ZU7wwjodsgUOPBoO7d57WWj3/rJeev6LgO/Z55jJihEOiykJhYf6ZueYCkXy/FvUfG07re6gfqc

declare module JSX {
  interface Element {}
  interface IntrinsicElements {
    [s: string]: any;
  }
}
interface ClickableProps {
  children: JSX.Element[] | JSX.Element;
}

interface HomeProps extends ClickableProps {
  home: JSX.Element;
}

interface SideProps extends ClickableProps {
  side: JSX.Element | string;
}

function MainButton(prop: HomeProps): JSX.Element;
function MainButton(prop: SideProps): JSX.Element;
function MainButton(prop: ClickableProps): JSX.Element {
  // ...
}

T5Dfdx/a6a+UGG4pALA5oL6Es3VL64Icfe6txQ+8FTX4Pvf9jQ5d7M7Me1NQukcOZB6hFswMUGrmSvyeKxuC6Y2QQlTbSaHYA0R9/0VFbvnn/c6FUdp1JsWqoUPCckeRMB8kI4Arm6IWmdK5GzanTu1AFrzDjbXPfgQLs/pL4woKIVjNvNj+EvcxIi/DDb+J6bLVg9AHNrzgtoDCR5uuDCzWnatL2M2c8kBMjQZqq/1wCeIUvj2MPOED59DgAk3a7bwswrffbN+rof1yME5nAoatNbHayspZK+oaaf8vxnAK+3P0hMA0G2O3BUx8ot4D

类组件

6/amlfhdGNo5UekLnsFvCdGAYfkUaei5oGiVG92AviCnf3PKY8LJLreGchCUcugIiw61lKeJNzYCRHZVs8DT29kXph5sqNH/K4QVAIbWVqoRN1yYk5ATQvHGTTIi9xp8fCP4y+hQRQNJUmNPt2JR0Wtj0U1DxrmGiS2rigbueiU=

KZDJAyi0gOPUR6jQpzhEEi3lAHIASrB5m+WDYPZKJqMb9hgZcuHPGyO2Ia5FMZmVZjZSHjEOP1nOaSx3CNCbNY5ywg5b340uPMmRaVasBJGoApkokOOGqK0Df2LtI6nLnC868zCwxeRaT5ZrZ2K9HL6IkCrcvA9r1UqYXKpHjMVIKI0g2s3UfUioZseN6HzfCiOYw9f817dXH5IGP67wrj3DPIncwjuB6qqskao/nJBRmqCGtz0zSYIx2y6XItu3vHNtuyUCaG01/UzenNwWmLc+UQGu7qmkm35juM7NGHV7tb+MnNafMsmg4M5OMGUkmo3JtjFzYaMmBvJV9dPIdMVdoeD0TkVqBXk0/VdCUPAlvvaXkzT+aL7LfHyf6TVfaYKZk/jORgRUUnzwPvogdl0L2MhvQgevoq3pKdANRQk+QjAtZbJ5E0LkLESqTKBZ

3mrajPLYqQ5/QofwEAYACnu5rBpN+s5Je4p5IGgeXPZU4d2MjYwe2VJwvqFfePxLZ0z6aHtiVOZD8n+c1b/J2cz2gu1Mb+PwGLzl4UEjvi30/iyg9V8LA2t3qdPdZvBYx0H1ShuafLH1pcn2UuyPqjn1jZc07z9i1HW/H10Z2mMjIaRqsJCA0gN7CNBomPC0VE0TbGFq36mLIAnrc7Ap/t+Rp+sSXMtqg4/nzxflT0ni1uErpNndaFO2VALWp8UZRld3N8dlLrVXnhwJvVl+FzMunZuC+4f9/zUvNmySA0H4Ol40LuPKiIRGtAv7ayQO4exE5CkzK1nl+PLLg0gFXe/LgZ123YWuohwc+bBvY+qPFzzZqbJMRRAZTYyUK0+j

class MyComponent {
  render() {}
}

// use a construct signature
const myComponent = new MyComponent();

// element class type => MyComponent
// element instance type => { render: () => void }

function MyFactoryFunction() {
  return {
    render: () => {},
  };
}

// use a call signature
const myComponent = MyFactoryFunction();

// element class type => MyFactoryFunction
// element instance type => { render: () => void }

xGo1pKXQfDt5JAvsEyXpiV0Z9YZWHfRv6dbDZmPfw5cII8OLPXzrWuRCX4lTKOIVm3zLfQ7ma4ZHPyN4e1oY++XQoXe0KDcM4oSVH/R6mujSzISyFp4pX7AuwopWB5w1AiNGeh5GiYFo1G5yQpVZoztlGpeJ5Ezn9VeazJvz90klZqxBpjPO1/oXTJqsBfGu3QDqC8RyfYmGTKG1VOzS1QAe8APbzZuATum/8ImTGf+OxxbiWIX9z5kFMmJ5Gh93+WgCjEYjZ8FHCYmrQHDXtjqf2SnVGOYcJ/+oD9s3krA66Thnqa+gFMGIZEehJ2p31b0+Bwe2Xe5yOe811j0pKhyDlKEfUL6/0saE1bg6R7Y=

declare namespace JSX {
  interface ElementClass {
    render: any;
  }
}

class MyComponent {
  render() {}
}
function MyFactoryFunction() {
  return { render: () => {} };
}

<MyComponent />; // ok
<MyFactoryFunction />; // ok

class NotAValidComponent {}
function NotAValidFactoryFunction() {
  return {};
}

<NotAValidComponent />; // error
<NotAValidFactoryFunction />; // error

属性类型检查

GLFCr4bbziNz6XwBng8N036AOviVhsLhYt53n6of86lKhQd6tYF7wH7bBYR8VxhQiNDmCHMwr5I6ba5Rkpmip2fmntdnqgs8hYMYqRkzjsziQ0cjL7dczBLol1nlf47BehxZoyedgtnNReIof9lxYV/ZNyI6ou/BZj3HoZC5Ns8=

4I2SGNvWWU+XAyGEogxHQu4sJiHUUarKsF9HfWQPGyzm/T+ftFp/Z3q4NJXMkAgdDOpKTOxNvMeKP36fdxbf7BvpEmrAU4gMlcfwyuOc+RLayhacOGA7QbCNCBhCUIPF

declare namespace JSX {
  interface IntrinsicElements {
    foo: { bar?: boolean };
  }
}

// element attributes type for 'foo' is '{bar?: boolean}'
<foo bar />;

3Y5MSUmDFJOsnhR8fNxQMXDqqVYD6nyWjo5gRFhBuoQkNiARxfh0iNCtazbiNK6R8kuRaOyDw56J8ISgOzCQkOmEx+UL+tqDvkQfWVcJK4wMZKWRrkKIORTct0K+2TUd89/FDVExYM/2K7lygEGFqoXS8vutNEev+3QmFwWODeMwa2J4mMOCPvg5ST69FRtqNSrLKY7bBfPdWB3X3EFXUEbnOczcDTEiR6dopKple98skmmVro8eEP3ZxTRgPVtoSQVPfHn0ZZi84QLckvvJP1QLJMshYJoXizORdfIGvZtHqWqCtQ+9zlhOnbA2cw7MqJ72wMqXqD+M1CoCpyKhyQhKqskTuRfnDwTVG1q5KT1fr2z/qZhmVajdzWIfUf5OHPtTzjNX8m/MyBy7VZ7P2+0jflN4LKP08qRpcwfgvHwP+e7j3zh9ipgYwMV5YWWB9GNxeiFyF7NX6+9EdTJbXWYWGpVD9narvFv33gEuDPOJnrrtl/lGUrNrEFdHlgoPOhJbi7sFA6cyxqmQP4Q6uz46CmBmMLWo6Mzb+8vqz6euu9wONW1IbyGjIclRFl3r

declare namespace JSX {
  interface ElementAttributesProperty {
    props; // specify the property name to use
  }
}

class MyComponent {
  // specify the property on the element instance type
  props: {
    foo?: string;
  };
}

// element attributes type for 'MyComponent' is '{foo?: string}'
<MyComponent foo="bar" />;

rnKpOBnERzZrCwCm0BgIFLG+1YcHyAXpX0yDv90cddF20uSRAfhaO5H6Xi5gGoifBWZfKQuBiPkDUYEDtWXTY5sh/RLmFE65Gcnw0L0sPU7IU0KO28NEkQigWmCtzmvwTZqSxcqDJFKnTV/8XEMBWw==

declare namespace JSX {
  interface IntrinsicElements {
    foo: { requiredProp: string; optionalProp?: number };
  }
}

<foo requiredProp="bar" />; // ok
<foo requiredProp="bar" optionalProp={0} />; // ok
<foo />; // error, requiredProp is missing
<foo requiredProp={0} />; // error, requiredProp should be a string
<foo requiredProp="bar" unknownProp />; // error, unknownProp does not exist
<foo requiredProp="bar" some-unknown-prop />; // ok, because 'some-unknown-prop' is not a valid identifier

sVpDZrypg0zY15y0Fq8vuhqRBcREImK8zC4siXpPmF2mwLrf+Y28vLUj9nbzeC4q0slHeB1SuqPGK0ebyZWL3K8RrJ/flY6EkYmjv4HI0eF6ls2P/IUZXyElcdWU+p/YbiP0lDrGDD55TnfQwbwn1CIE6GCQPXgt1iMRrrS7vMXK7t+Ag12VAJIAUpfwFAiJMMB4CnCy39sUFtT1F9Yn/hNFK4//V+F4CLCxwb6TXdk=

lX4KOJkRgRh+ixxCWBhF2gV1DAyjJRiq1N31894QwjbxzOtB6uq4BwVLHwDI93lcR9FudgjP0ahm//VqweMHoiAf5HiLZ+zs923zrTCRQoKAaGNFL2j1E1ByS2l8tdt9fRDXNV0BqnOPVfTmPr0YopKlXbQHq0jiEvZR1z5GTAOFEFN2e9qbKQDgAnmHd1w+FKv0vER6NAiVvID7bGpJIpEdE9PmBoSzTo/T0GTvltZdgH97VDLLR11jzaWAcmyf57sNxlhoI5vVrt//aPrG+Jf/M9Gja4iOHn2yVsth336sobM4CnpG5MwNDdU7XxDSy0njYOgKU9zuQAILQwQTyNneILD1PCLbtYdzW1Lt5gjxaU6DzPULKDVAMT/xzaBuwDt/N7PhCO0jqmSe/WQCp3Xr+jz3cSJBrmgdm4SmjoQl3oXGsyXFD6UDdKIZf22xtDsT1FO4+5qhfUN8t/9ph1+soqLiECK6d0RP5THuDBWnWnDKB8JZ0T0HX/9wUVMKjaelZCDKl8TBXMAEm/1AeLRxeIUZHsYk28t5+dCB9TvOEy4bLlnlLFtfa8SAUD3B/kX5/Mj/oOsjsz5Px3f9YPbU1tAFcbsm7QdzKrPYK1ySMqLq2wvZRLrHnRLaogtIZWe1UYyWd+qXcU6efaGi7rzo8L55cjv1MZYG8icbAkIY1ylU+jRcZZJU7TwBIE5oxGUfZ3HzlwO19DLjedxYHF+EvsPnN74uEp5TBXJ0wmelqz/fbdqcLYjPEQORIDA6TjNe+8yrpj+0Yhqa9+3SvDxvbDc7OcBNHf+lXLVZf/4DI/cxCFXJdq+MGh0Ajx3p9vQDbwVpChiF5V8G9nXhdEHdywn7xJuoLq+ppvUmzZvK2+9A7RC7B9hLLAmYLna7Jy3tnke0VQQE8I/oae/07g==

r0TRKrc9In69tT8bxfTb7di2jOS1jYl3FpgvDPRq1HM=

const props = { requiredProp: "bar" };
<foo {...props} />; // ok

const badProps = {};
<foo {...badProps} />; // error

子类型检查

6kybOgzT6VZ1tbO2zS1xRZ437692XDEV6KKy4349WoUMIINSYvY03iJ/KiJwYwuwgIDJo/i7Y10srm4Sg+TIgVnUUAlj22myx7qJ3kFFqxgTk/zszg91fnSoPsEq5GaUZqp+ynl0ShmzseNClYb5UyzM1zvx487wEzyKC98Krstr9sOk5rhWScmL9pim/Q24q9OU0QrzAvmWu/HJFH24BhaQaQJK0W6RPAOeFRrv2hv3ymXORONqwPGaeuWzE8X13xIHzjnXHpZH7AIVuHR+h0wQRcDqHwojZ1sVXIQpQUb8WWklyqTaL8IT2ZL1Ua51SEmI9RGkX3e3KGX8ROZ7qd7frbY2yF4zEgf4aYLc1IJ4bBFgFej5zAyu7VmqWZFaWlJ2RZJNFtWsC0C5/zA67BOVvr/Q3hiq3Lg6mCmBFwjIGsIHRPShdG+035vtvzfcc+jpq1j0d50tCIVR6uyHjuGZBNB6DoSTK3+P2q6nUV4qq4TljpQbIP39+cWWG/6To3dyIGwnh+XjdAd7Fm2zZg8hzChllcvb/KwD/bjqWjnwCv72qA6dCxZehetN0qrz

declare namespace JSX {
  interface ElementChildrenAttribute {
    children: {}; // specify children name to use
  }
}
<div>
  <h1>Hello</h1>
</div>;

<div>
  <h1>Hello</h1>
  World
</div>;

const CustomComp = (props) => <div>{props.children}</div>
<CustomComp>
  <div>Hello World</div>
  {"This is just a JS expression..." + 1000}
</CustomComp>

urH4gc0spiws/Tida9oViSRo6SUyHMKo4axi3RvxILhRY6OgJTU6cy6iBHex9pZAoMJvyvIQAdoTb/BFEGRlq7B3UACUPwZQtqJ99zYn70zOQ9MeRxuS/DPRi37myTgcpjG93dmHBZZkVyclEpuVO28CMfMAJkFaLRavtAV/3xouljon+SUgiY6tyAqTYI4NebyY1IIiCUq7Xd07FzuEcS2eMBj4Y8CF/gstm3c1T8GBAZaBNJZypZtC21jVZrL6

interface PropsType {
  children: JSX.Element
  name: string
}

class Component extends React.Component<PropsType, {}> {
  render() {
    return (
      <h2>
        {this.props.children}
      </h2>
    )
  }
}

// OK
<Component name="foo">
  <h1>Hello World</h1>
</Component>

// Error: children is of type JSX.Element not array of JSX.Element
<Component name="bar">
  <h1>Hello World</h1>
  <h2>Hello World</h2>
</Component>

// Error: children is of type JSX.Element not array of JSX.Element or string.
<Component name="baz">
  <h1>Hello</h1>
  World
</Component>

JSX 结果类型

9ABsrJ/m6DeAkcxT/pHN0/FBLqlDYrZwpB4ZnGNTkVBnBlK59895kWlRISnUGxbTy2srqKTxeOFDo+i9CTAlv3IWPNApnUE+yXCvjFAzXqb7HGBJG4jV2wlH3BjZCytjv3NjcrFJYfFeE1Bkmwd7oOmHMQ1s4mrEdJ3MHFcfycNpedc/jeNRiNPf1/4bWbTjEabmLdkeq7fhvq5szKybb5g+l8VY1jzdlf3UfI3wUDl0gW/jOJcaSfG/s0s7bqlru57WYnmwm4G3Viiosur5aFii+2Ob0s9K235VP1saWFL/LYXqA6Na9vPrV8FlQgOTQTDGyvI3Q/MA4+iW214PHUJF3KNBhn06RlghcwjkGhY=

嵌入表达式

bJ0ODF1P/92gjouVjBnCLj/uiwrOuyYpy87CIlpK+VilA3npGwfKOs28J762FnBjgyzLtcpGSGKxRwZuhB2dN9IMupnddRe21HG5ZbQSVEWZxmhPTJ0KogDZuErMM+pr7O2/SvWAbLLAObxduIsz7Q==

const a = (
  <div>
    {["foo", "bar"].map((i) => (
      <span>{i / 2}</span>
    ))}
  </div>
);

jrBFTvIOdHd9eozI8J+9aQi+59UQlQ9kHCU3pVB+ctxvfcejGcYHvBTsf+A6gHdCzOrsT4cLHE7xPWEnIRvYbspjg2y+quFpeY4RernZ8EeJeX1gY6Nkwjdz+zXLRoVAz6Ubs+UzxgsoWJ0sARVn3xt7YmKlL/9ebUZNeUp6i4bT+QdBe4ioNZn8HujHTM8O

const a = (
  <div>
    {["foo", "bar"].map(function (i) {
      return <span>{i / 2}</span>;
    })}
  </div>
);

React 集成

a3zktNV7m9SBLvugy9m8KibBOZ72yHCcjRD9VeyoZCeP7Rg9uvJwi7mfQWBOvArCWYNviBW7WhTcDwSx1TAdWye9bOjQarMQlcX8D67ubLgrNhiiox9aSQ3GCEZfQe69rXjcJm46le6ZfXv4jsyjk7mQYR7sleungMymtPLY0my41/6hBMPnZ9w+MfpcDAHFiAfRig8/VQaj1RO/k7RU07vfVEpPiP6Hx3yCyGZNU19bXBqH3nqcJw2yL/k5o/WOu0b+ca4zhE6g8YNNBvglXQ==

/// <reference path="react.d.ts" />

interface Props {
  foo: string;
}

class MyComponent extends React.Component<Props, {}> {
  render() {
    return <span>{this.props.foo}</span>;
  }
}

<MyComponent foo="bar" />; // ok
<MyComponent foo={0} />; // error

配置 JSX

+tZhJTfpX5U3PjvQY9PFWVIY2IoRkAlZ4J5TeUIPq7om/Oq5ue23FpNFeKBqv97kdfrpN1pCRTGD3by8CdbCdoVqt8gBSE5O+VKPr0n/AAQKcaBoNVaZs4A4RHB3Yuk5F0HpfSMbw7LG3cyvhbGkJri+MWrNc07awC3/CftLDoFXbo7ZS9ZlMb6VDuykd+Z7dC8FI2dIP6UMvpBQksRmUfLnblWKv23BKfaAaso8rMX1vyuysnSR95QaJYz2JplK/1PJOQHPdyhHG7IWJ00DOw==

    Ztf6kTKo+rF5kKx7RUx6kbimz8WlN1q60/QsoV6wBfE7wS1chP+vZPW3eTGN94ddz7QpY9kb1xPMX3OlKiks+fXT4GQuUVjJRXYbLOfCCLPFS6IKkMHgChzfSF7GsL0qEfpFTa8usvRSVEILs0k4XEiNaD8ofsSFdBzb+JUjmGTJcdL1lgRtXL8j40Fb37SuLb6LnXaCXilFk/BQn0FAlG3ssXhib3PVG8+qFuNy1fEWhcHRZsNLWJfkGRZu9MGrN+Ka8VLuIgtdJuwvRu+J0WhVBMGHXn8Hm17HiIb9nBnz9wa/hUN7g6ycf1UUD8if1gY5yP6jheui4Pa8WwKxwcvuZAVLEg11jPZCI4bpVRI=