Библиотека SWC (Speedy Web Compiler) предоставляет полноценную поддержку синтаксиса TypeScript и способна выполнять высокоскоростную трансиляцию исходного кода в JavaScript без участия компилятора TypeScript. Основная задача SWC заключается в преобразовании типизированного кода в исполняемый JavaScript с удалением всех конструкций, используемых исключительно во время проверки типов.
Поддержка TypeScript является одной из ключевых возможностей SWC, поскольку современные веб-приложения активно используют типизацию для повышения надежности кода, улучшения поддержки IDE и упрощения сопровождения крупных проектов.
SWC понимает большинство возможностей языка TypeScript и корректно обрабатывает их на этапе трансформации.
Наиболее распространённой конструкцией TypeScript являются аннотации типов.
Исходный код:
const name: string = "John";
const age: number = 25;
После обработки SWC:
const name = "John";
const age = 25;
Типы полностью удаляются, поскольку они не существуют во время выполнения программы.
Поддерживаются:
Пример:
let value: string | number;
Результат:
let value;
Интерфейсы используются исключительно системой типов и не влияют на выполнение программы.
Код TypeScript:
interface User {
id: number;
name: string;
}
После трансформации:
Интерфейс полностью исчезает из итогового JavaScript.
Более сложный пример:
interface Employee extends User {
department: string;
}
Результат:
SWC удаляет все объявления интерфейсов независимо от уровня вложенности и сложности наследования.
Псевдонимы типов также относятся исключительно к системе типизации.
Исходный код:
type UserId = number;
type User = {
id: UserId;
name: string;
};
После преобразования:
Все объявления type удаляются.
Поддерживаются:
Пример:
type ApiResponse<T> =
| { success: true; dat a: T }
| { success: false; error: string };
После трансиляции:
Обобщения (Generics) широко применяются для создания переиспользуемых компонентов.
Код:
function identity<T>(value: T): T {
return value;
}
Результат:
function identity(value) {
return value;
}
Параметры типа удаляются полностью.
Пример с несколькими параметрами:
function merge<T, U>(a: T, b: U): T & U {
return {
...a,
...b
};
}
После обработки:
function merge(a, b) {
return {
...a,
...b
};
}
SWC корректно обрабатывает обобщённые классы.
Исходный код:
class Repository<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
}
Результат:
class Repository {
items = [];
add(item) {
this.items.push(item);
}
}
Вся информация о типах удаляется.
Перечисления являются одной из немногих конструкций TypeScript, которые генерируют JavaScript-код.
TypeScript:
enum Status {
Pending,
Active,
Archived
}
SWC генерирует:
var Status;
(function(Status) {
Status[Status["Pending"] = 0] = "Pending";
Status[Status["Active"] = 1] = "Active";
Status[Status["Archived"] = 2] = "Archived";
})(Status || (Status = {}));
Создается объект с прямым и обратным отображением значений.
Исходный код:
enum Role {
Admin = "admin",
User = "user"
}
Результат:
var Role;
(function(Role) {
Role["Admin"] = "admin";
Role["User"] = "user";
})(Role || (Role = {}));
Обратное отображение для строковых значений не создается.
Константные перечисления могут быть встроены непосредственно в код.
Исходный пример:
const enum Direction {
Up,
Down
}
const current = Direction.Up;
После трансформации:
const current = 0;
Подобная оптимизация позволяет избежать генерации дополнительного объекта перечисления.
SWC поддерживает пространства имён TypeScript.
Исходный код:
namespace Utils {
export function log(message: string) {
console.log(message);
}
}
После преобразования:
var Utils;
(function(Utils) {
function log(message) {
console.log(message);
}
Utils.log = log;
})(Utils || (Utils = {}));
Пространство имён преобразуется в JavaScript-модуль на основе IIFE.
TypeScript предоставляет набор модификаторов доступа:
public
private
protected
Пример:
class User {
private password: string;
protected token: string;
public name: string;
}
После обработки:
class User {
password;
token;
name;
}
Модификаторы удаляются, поскольку они не влияют на выполнение программы.
TypeScript позволяет одновременно объявлять свойства класса и параметры конструктора.
Код:
class User {
constructor(
private id: number,
public name: string
) {}
}
SWC генерирует:
class User {
id;
name;
constructor(id, name) {
this.id = id;
this.name = name;
}
}
Создаются соответствующие свойства и инициализация внутри конструктора.
Абстрактные классы поддерживаются и преобразуются в обычные классы JavaScript.
Исходный код:
abstract class Animal {
abstract speak(): void;
}
После трансформации:
class Animal {
}
Ключевые слова abstract удаляются.
Более сложный пример:
abstract class Animal {
abstract speak(): void;
move() {
console.log("moving");
}
}
Результат:
class Animal {
move() {
console.log("moving");
}
}
Абстрактные методы существуют только на уровне типов.
TypeScript:
abstract class Service {
abstract execute(): void;
}
Jav * aScript:
class Service {
}
Метод полностью удаляется.
SWC поддерживает оба синтаксиса приведения типов.
Конструкция через as:
const element = document.body as HTMLBodyElement;
Результат:
const element = document.body;
Конструкция через угловые скобки:
const value = <string>data;
После обработки:
const value = data;
Оператор ! сообщает компилятору о гарантированном
существовании значения.
Исходный код:
const text = element!.textContent;
Результат:
const text = element.textContent;
Оператор полностью удаляется.
Конструкция используется для полей класса.
TypeScript:
class User {
name!: string;
}
После трансформации:
class User {
name;
}
TypeScript позволяет импортировать сущности исключительно для проверки типов.
Исходный код:
import type { User } from "./types";
После преобразования:
Импорт удаляется полностью.
Поддерживаются также экспортируемые типы.
Исходный код:
export type {
User,
Product
};
После обработки:
Подобные конструкции не попадают в результирующий код.
TypeScript содержит специальную форму импорта.
Пример:
import fs = require("fs");
SWC способен обрабатывать подобный синтаксис в зависимости от выбранной конфигурации модулей.
После преобразования CommonJS:
const fs = require("fs");
SWC поддерживает синтаксис декораторов при соответствующей настройке парсера.
Пример:
@Controller()
class UserController {
}
После трансформации декоратор преобразуется в вызовы вспомогательных функций согласно выбранной стратегии компиляции.
Поддерживаются:
Конструкция:
class User {
readonly id: number;
}
После обработки:
class User {
id;
}
Ограничение на изменение значения существует только во время проверки типов.
Необязательные свойства поддерживаются полностью.
Исходный код:
interface User {
name?: string;
}
После трансформации:
Поскольку интерфейс удаляется, информация о необязательности свойства также исчезает.
Код:
function greet(name?: string) {
console.log(name);
}
Результат:
function greet(name) {
console.log(name);
}
Объединения типов используются исключительно системой типов.
Исходный код:
let value: string | number;
После преобразования:
let value;
Пример:
type User = Person & Employee;
После обработки:
Пересечения удаляются вместе с типовыми объявлениями.
Код:
type Method =
| "GET"
| "POST";
Результат:
Литеральные типы не оказывают влияния на итоговый JavaScript.
Условные типы являются одной из самых мощных возможностей TypeScript.
Пример:
type IsString<T> =
T extends string
? true
: false;
После трансформации:
SWC полностью удаляет подобные конструкции.
Исходный код:
type ReadonlyUser = {
readonly [K in keyof User]: User[K];
};
Результат:
Все отображаемые типы устраняются во время компиляции.
Поддерживается синтаксис вывода типов через infer.
Пример:
type ReturnType<T> =
T extends (...args: any[]) => infer R
? R
: never;
После преобразования:
Поскольку механизм работает исключительно на уровне типов, итоговый JavaScript не содержит никаких следов подобных конструкций.
Ключевое слово declare используется для описания внешних
сущностей.
Код:
declare const API_URL: string;
Результат:
Объявление удаляется полностью.
Пример:
declare namespace Library {
function init(): void;
}
После трансформации:
Все декларативные пространства имён исчезают из результирующего кода.
Типовые объявления модулей также поддерживаются.
Исходный код:
declare module "*.svg" {
const content: string;
export default content;
}
После обработки:
Такие конструкции существуют исключительно для системы типов.
Поддержка TypeScript в SWC строится вокруг фундаментального принципа: всё, что относится исключительно к типизации, удаляется, а всё, что имеет влияние на выполнение программы, преобразуется в эквивалентный JavaScript-код.
К конструкциям, генерирующим JavaScript, относятся:
enum;
const enum (с возможной инлайновой подстановкой);
namespace;
Полностью удаляются:
Благодаря такому подходу SWC обеспечивает чрезвычайно быструю трансиляцию TypeScript-кода и успешно используется в современных сборщиках, фреймворках и инструментах разработки как высокопроизводительная альтернатива традиционному компилятору TypeScript.