Название фичи: JSX
Описание:
JSX - встраиваемое XML-подобное расширение синтаксиса JavaScript. Он трасформируется в корректный JavaScript, однако семантика такого преобразования зависит от конкретной реализации. TypeScript поддерживает встраивание, проверку типов и преобразование JSX в JavaScript напрямую.
Детали:
Для использования JSX, необходимо:
- Назначить файлам расширение
.tsx
- Включить опцию
jsx
TypeScript имеет три JSX режима: preserve, react и react-native. Режимы влияют только на стадию генерации (проверка типов не изменяется).preserve
сохраняет JSX в выходном коде, который далее передаётся на следующий шаг трансформации. Выходной код получит расширение.jsx
.react
сгенерируетReact.createElement
, где не не требуется трансформировать JSX перед применением, и код на выходе получит расширение.js
.react-native
эквивалентен preserve
в сохранении JSX в выходном коде, однако выходной код получить расширение .js
.
По умолчанию результирующим типом выражения JSX является тип any. Тип можно изменить путём определения интерфейса JSX.Element. Однако невозможно получить информацию о типах элемента / атрибутов / потомков JSX из интерфейса.
Для проверки типа атрибутов необходимо в начале определить тип атрибутов элемента (element attributes type). Эта процедура отличается для внутренних элементов и элементов-значений.
Аналог в React: JSX
Решаемая проблема:
Определение синтаксиса для определения древовидных структур с атрибутами.
Как решить проблему:
Универсальный, но четко определенный синтаксис позволяет сообществу независимых парсеров и синтаксических маркеров соответствовать единой спецификации.
Синтаксис:
//декларирование типов
var foo = bar as foo;
//JSX позволяет вставлять выражения между тегами, заключая их в фигурные скобки ({ })
var a = <div>
{["foo", "bar"].map(function (i) { return <span>{i / 2}</span>; })}
</div>
//проверка типа атрибута
var props = { requiredProp: "bar" };
<foo {...props}="">; // ok
var badProps = {};
<foo {...badprops}="">; // ошибка
</foo></foo>
Перекомпилированный в JSкод:
var foo = bar;
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var a = (_a = {}, _a["foo", "bar"] = .map(function (i) { return { i: / 2}</span > }; }), _a)
< /div>;
var props = { requiredProp: "bar" };
(__assign({}, props));
"" > ;
var badProps = {};
(__assign({}, badprops));
"" > ;
/foo></foo > ;
var _a;