0Pricing
TypeScript Academy · Урок

Пользовательские преобразователи и генерация кода

Пишите преобразования компилятора, изменяющие AST

«Пользовательские преобразователи и генерация кода» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.

Что такое трансформеры

Трансформеры TypeScript — это функции, которые получают узел AST и возвращают узел, возможно изменённый. Они выполняются во время компиляции, чтобы создавать пользовательский результат.

import ts from "typescript";
type Transformer = ts.TransformerFactory<ts.SourceFile>;

Структура фабрики трансформера

Фабрика трансформеров принимает TransformationContext и возвращает функцию, преобразующую узлы SourceFile.

const myTransformer: ts.TransformerFactory<ts.SourceFile> =
  (ctx) => (sf) => {
    function visit(node: ts.Node): ts.Node {
      // Modify node here
      return ts.visitEachChild(node, visit, ctx);
    }
    return ts.visitNode(sf, visit) as ts.SourceFile;
  };

Обход с контекстом

ts.visitEachChild (а не forEachChild) используется внутри трансформеров, поскольку корректно пересоздаёт изменённые узлы.

function visit(node: ts.Node): ts.Node {
  if (ts.isStringLiteral(node)) {
    return ts.factory.createStringLiteral(node.text.toUpperCase());
  }
  return ts.visitEachChild(node, visit, ctx);
}

Создание новых узлов с помощью ts.factory

Объект ts.factory предоставляет методы для создания узлов AST всех видов.

const newCall = ts.factory.createCallExpression(
  ts.factory.createIdentifier("console.log"),
  undefined,
  [ts.factory.createStringLiteral("hello")]
);

Применение трансформеров к программе

Передайте трансформеры параметру customTransformers метода program.emit.

program.emit(undefined, undefined, undefined, false, {
  before: [myTransformer],
});

Генерация кода: печать узлов

Используйте ts.createPrinter, чтобы преобразовать узлы AST обратно в строки исходного кода без запуска полного компилятора.

const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
const result = printer.printNode(
  ts.EmitHint.Unspecified,
  newCall,
  sf
);
console.log(result); // console.log("hello")

Генерация целых исходных файлов

Вы можете создать полный исходный файл с нуля с помощью ts.factory.createSourceFile или собрать его из списка узлов операторов.

const statements = [
  ts.factory.createExpressionStatement(
    ts.factory.createCallExpression(
      ts.factory.createIdentifier("console.log"),
      undefined,
      [ts.factory.createStringLiteral("generated!")]
    )
  ),
];

Преобразование импортов

Распространённый вариант использования — преобразование путей импорта, например замена псевдонимов путей на относительные пути во время вывода.

if (ts.isImportDeclaration(node)) {
  const spec = node.moduleSpecifier as ts.StringLiteral;
  if (spec.text.startsWith("@app/")) {
    return ts.factory.updateImportDeclaration(
      node, node.modifiers, node.importClause,
      ts.factory.createStringLiteral(spec.text.replace("@app/", "../")),
      node.assertClause
    );
  }
}

Тестирование трансформеров

Тестируйте трансформеры, применяя их к небольшому исходному файлу и проверяя, что напечатанный результат совпадает с ожидаемой строкой.

const result = ts.transpileModule("const x = 'hello';", {
  compilerOptions: { target: ts.ScriptTarget.ES2020 },
  transformers: { before: [myTransformer] },
});
console.log(result.outputText);

Системы плагинов

Некоторые инструменты сборки (например, ttypescript / ts-patch) позволяют регистрировать трансформеры как плагины в tsconfig, делая их работу незаметной для процесса разработки.

// tsconfig.json with ts-patch:
// "plugins": [{ "transform": "./my-transformer.js" }]

Итоги: пользовательские трансформеры

Трансформеры позволяют переписывать код TypeScript на уровне AST во время компиляции. Используйте ts.visitEachChild для рекурсивного обхода, ts.factory для создания узлов и ts.createPrinter для генерации исходного текста.

Быстрая проверка

Какой объект используется для создания новых узлов AST в трансформере?

Что Вы узнали

Пользовательские трансформеры изменяют AST TypeScript во время компиляции. Используйте ts.visitEachChild для рекурсии, ts.factory для создания новых узлов и program.emit с customTransformers для их применения.

Часто задаваемые вопросы

Урок «Пользовательские преобразователи и генерация кода» бесплатный?

Да — полный текст урока «Пользовательские преобразователи и генерация кода» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «Пользовательские преобразователи и генерация кода»?

Пишите преобразования компилятора, изменяющие AST Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать TypeScript Academy?

Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Пользовательские преобразователи и генерация кода»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке TypeScript Academy?

Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Создание программы TypeScript с помощью API
  2. Обход AST с помощью посетителей
  3. Пользовательские преобразователи и генерация кода
  4. Создание простого инструмента проверки стиля кода
← Назад к TypeScript Academy