Documentation - JSX

Documentation - JSX

JSX 是一种可嵌入的 XML 类型的语法。它旨在转换为有效的 JavaScript,尽管该转换的语义是特定于实现的。JSX 在 React 框架中广受欢迎,但也已经出现在其他实现中。TypeScript 支持直接将 JSX 嵌入、类型检查和编译为 JavaScript。

基本用法

要使用 JSX,你必须做两件事:

将你的文件命名为 .tsx 扩展名

启用 jsx 选项

TypeScript 附带了三种 JSX 模式:preserve、react 和 react-native。这些模式仅影响输出阶段——类型检查是不受影响的。preserve 模式会保留 JSX 作为输出的一部分,以供进一步的转换步骤使用(例如 Babel)。另外,输出将有 .jsx 文件扩展名。react 模式将输出 React.createElement,在使用前无需经过 JSX 转换,输出将有 .js 文件扩展名。react-native 模式类似于 preserve,它保留了所有的 JSX,但输出将有 .js 文件扩展名。

模式

输入

输出

输出文件扩展名

preserve

.jsx

react

React.createElement("div")

.js

react-native

.js

react-jsx

_jsx("div", {}, void 0);

.js

react-jsxdev

_jsxDEV("div", {}, void 0, false, {...}, this);

.js

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

*备注:你可以使用 jsxFactory 选项指定目标 react JSX 输出时使用的 JSX 工厂函数(默认为 React.createElement)

as 操作符

回想一下如何编写类型断言:

tsconst foo = bar;

这会声明变量 bar 的类型为 foo。由于 TypeScript 也使用尖括号进行类型断言,与 JSX 的语法相结合会造成某些解析困难。因此,TypeScript 在 .tsx 文件中禁止使用尖括号类型断言。

由于上述语法在 .tsx 文件中不能使用,我们应该使用一个替代的类型断言操作符:as。示例可以很容易地用 as 操作符重写。

tsconst foo = bar as foo;

as 操作符在 .ts 和 .tsx 文件中都可用,它与尖括号类型断言的行为是相同的。

类型检查

为了理解 JSX 的类型检查,你首先需要了解内置元素和基于值的元素之间的区别。给定一个 JSX 表达式 ,expr 可能指的是环境中的某个内置元素(例如 DOM 环境中的 div 或 span)或者你自己创建的自定义组件。这一点很重要,因为:

对于 React 来说,内置元素会作为字符串(React.createElement("div"))输出,而你创建的组件则不是(React.createElement(MyComponent))。

传递给 JSX 元素的属性类型应该以不同的方式查找。内置元素的属性应该是内置的,而组件可能需要指定自己的属性集合。

TypeScript 使用与 React 相同的约定来区分这两者。内置元素总是以小写字母开头,而基于值的元素总是以大写字母开头。

内置元素

内置元素通过特殊接口 JSX.IntrinsicElements 查找。默认情况下,如果没有指定这个接口,那么一切都可以,内置元素不会进行类型检查。但是,如果定义了这个接口,那么内置元素的名称就会在 JSX.IntrinsicElements 接口上查找。例如:

tsdeclare namespace JSX { interface IntrinsicElements { foo: any; }}; // 正确; // 错误

在上面的例子中, 可以正常工作,但 会报错,因为它没有在 JSX.IntrinsicElements 中指定。

备注:你也可以在 JSX.IntrinsicElements 上指定一个通用的字符串索引器,如下所示:

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

基于值的元素

基于值的元素只需要查找当前作用域内的标识符。

tsimport MyComponent from "./myComponent";; // 正确; // 错误

有两种定义基于值的元素的方式:

函数组件

类组件

因为这两种类型的基于值的元素在 JSX 表达式中是无法区分的,所以 TypeScript 首先会尝试使用函数组件的重载解析来解析表达式。如果成功,则 TS 会完成对该声明的解析。如果无法解析为函数组件,则 TS 会尝试将其解析为类组件。如果仍然失败,TS 会报错。

函数组件

顾名思义,组件被定义为一个 JavaScript 函数,它的第一个参数是一个 props 对象。TypeScript 强制要求它的返回类型必须可赋值给 JSX.Element。

tsinterface FooProp { name: string; X: number; Y: number;}declare function AnotherComponent(prop: { name: string });function ComponentFoo(prop: FooProp) { return ;}const Button = (prop: { value: string }, context: { color: string }) => (

相关推荐