深入理解Typescript系列-TSX

10,739 阅读1分钟

这是我参与 8 月更文挑战的第 18 天,活动详情查看: 8月更文挑战

前言

JSX是一种可以在JavaScript中描述HTML的语法,尽管转换的语义是依据不同的实现而定的。 JSX本身也是一个表达式,在编译后,JSX表达式会变成普通的JavaScript对象。JSX因React框架而流行,但也存在其它的实现。 TypeScript支持内嵌,类型检查以及将TSX直接编译为JavaScript。

初探

写过react的同学应该接触JSX比较多了,而TSX和JSX的关系就像JS和TS,我们只要搞明白JSX,那TSX也就不难了。

import React from 'react'

function render(props) {
    return <div>{props.title}</div>
}

经过编译后,会变成如下浏览器可直接执行的js代码

import React from 'react'

function render(props) {
    return React.createElement('div', null, props.title)
}

本质上,TSX为我们提供了创建React元素方法(React.createElement(component, props, ...children))的语法糖(syntactic sugar)。

as操作符

回想一下怎么写类型断言:

var foo = <foo>bar;

但是在TSX中,<>会被认为是一种HTML描述,存在语法上的冲突,所以我们需要改成这样:

var foo = bar as foo;

类型检查

对于一个TSX的表达式,返回的类型是根据输入而定的。本质其实是React.createElement的返回值。对于React,固有元素会生成字符串(React.createElement("div")),然而由你自定义的组件却不会生成(React.createElement(MyComponent))。

// 返回原生DOM类型
function render() {
    return <div></div>
}

// 返回Car类型
function render() {
    return <Car />
}

// 返回字符串类型
function render() {
    return 'xxx'
}

...

表达式

在Vue中,有v-if、v-for等表达式来描述业务逻辑,而在TSX中,则可以直接调用JS的原生能力。

在TSX中,常有的表达式如下:

  • 变量名;
  • 函数定义表达式;
  • 属性访问表达式;
  • 函数调用表达式;
  • 算数表达式;
  • 关系表达式;
  • 逻辑表达式;
function render(props) {
    if (props.dataList.length === 0) {
        return null;
    }
    return (
        <div>
            {props.dataList.map(item => <Item>{item}</Item>)}
        </div>
    )
}

小结

JSX在React中使用给我们带来了很大的便利,而TSX,弥补了JSX缺乏类型系统、类型校验等弊端,大大降低了我们代码出错的概率。