Jest

基于 Jest 的 React 组件测试

JSX

TypeScript 具有三种 JSX 模式:preserve,react 和 react-native。这些模式只在代码生成阶段起作用,类型检查并不受影响。

  • 在 preserve 模式下生成代码中会保留 JSX 以供后续的转换操作使用(比如:Babel)。另外,输出文件会带有.jsx 扩展名。

  • react 模式会生成 React.createElement,在使用前不需要再进行转换操作了,输出文件的扩展名为.js。

  • react-native 相当于 preserve,它也保留了所有的 JSX,但是输出文件的扩展名是.js。

假设有这样一个 JSX 表达式<expr />,expr 可能引用环境自带的某些东西(比如,在 DOM 环境里的 div 或 span)或者是你自定义的组件。这是非常重要的,原因有如下两点:

  • 对于 React,固有元素会生成字符串(React.createElement("div")),然而由你自定义的组件却不会生成(React.createElement(MyComponent))。
  • 传入 JSX 元素里的属性类型的查找方式不同。固有元素属性本身就支持,然而自定义的组件会自己去指定它们具有哪个属性。

TypeScript 使用与 React 相同的规范 来区别它们。固有元素总是以一个小写字母开头,基于值的元素总是以一个大写字母开头。

固有元素

固有元素使用特殊的接口 JSX.IntrinsicElements 来查找。默认地,如果这个接口没有指定,会全部通过,不对固有元素进行类型检查。然而,如果这个接口存在,那么固有元素的名字需要在 JSX.IntrinsicElements 接口的属性里查找。例如:

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

<foo />; // 正确
<bar />; // 错误

在上例中,<foo /> 没有问题,但是 <bar /> 会报错,因为它没在 JSX.IntrinsicElements 里指定。

基于值的元素

基于值的元素会简单的在它所在的作用域里按标识符查找。

import MyComponent from "./myComponent";

<MyComponent />; // 正确
<SomeOtherComponent />; // 错误

工厂函数

jsx: react编译选项使用的工厂函数是可以配置的。可以使用 jsxFactory 命令行选项,或内联的@jsx 注释指令在每个文件上设置。比如,给 createElement 设置 jsxFactory,<div /> 会使用 createElement("div") 来生成,而不是 React.createElement(“div”)。

注释指令可以像下面这样使用(在 TypeScript 2.8 里):

import preact = require("preact");
/* @jsx preact.h */
const x = <div />;

生成:

const preact = require("preact");
const x = preact.h("div", null);

工厂函数的选择同样会影响 JSX 命名空间的查找(类型检查)。如果工厂函数使用 React.createElement 定义(默认),编译器会先检查 React.JSX,之后才检查全局的 JSX。如果工厂函数定义为 h,那么在检查全局的 JSX 之前先检查 h.JSX。

上一页