Проверка типов после запуска плагина / трансформера компилятора Typescript - PullRequest
0 голосов
/ 23 ноября 2018

Я слежу за блогом (https://dev.doctorevidence.com/how-to-write-a-typescript-transform-plugin-fc5308fdd943) о том, как написать плагин / трансформер компилятора Typescript.

После применения первого простого преобразования, которое должно привести к ошибке типа (к некоторым свойствам обращались)на объекте, у которого нет этого свойства) Я заметил, что ошибка типа не отображается. Фактически, компилятор работает как обычно.

import * as ts from "typescript";

export const transformerFactory = (
  program: ts.Program
): ts.TransformerFactory<ts.SourceFile> => {
  return (context: ts.TransformationContext): ts.Transformer<ts.SourceFile> => {
    const visitor: ts.Visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
      if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
        if (node.expression.escapedText === "someCall") {
          return ts.createCall(
            ts.createPropertyAccess(node.expression, "nonExisting"),
            node.typeArguments,
            node.arguments
          );
        }
      }
      return ts.visitEachChild(node, visitor, context);
    };

    return (sf: ts.SourceFile) => ts.visitNode(sf, visitor);
  };
};

Применимо к index.ts:

declare function someCall(...args: any[]): string;

console.log(someCall(1, 2, true));

Выход index.js:

console.log(someCall.nonExisting(1, 2, true));

(даже с noEmitOnError: true)

Это предполагаемое поведение? Это то, что я могу где-то включить?

1 Ответ

0 голосов
/ 23 ноября 2018

Это предполагаемое поведение?

Да.

Можно ли это где-то включить?

Нет, трансформаторы имеют ограниченное назначение.Общие универсальные «плагины» для компилятора не поддерживаются.

Трансформаторы запускаются как часть фазы «emit», которая генерирует код JavaScript из проверенного типа AST.

Этот комментарий в PR-преобразователе гласит:

Все преобразования происходят после фазы проверки

ОБНОВЛЕНИЕ

есть ли способ компилировать дважды: один раз для преобразования файла и один раз для проверки всего типа?Я не против, если мне придется выполнить отдельную проверку для преобразованных файлов.

Я не знаю.Первое, что нужно попробовать, это сделать так, чтобы ваши преобразователи модифицировали AST, как и раньше, а затем проверить тип измененных файлов вручную, вызвав

program.getDiagnosticsProducingTypeChecker().getDiagnostics(sourceFile)

(getDiagnostics имеет второй параметр - cancellationToken - но кажется, что этоего можно опустить, потому что он всегда проверяется на соответствие undefined в коде проверки типов. В общем, вы можете посмотреть, как различные API-интерфейсы компилятора используются в его собственном исходном коде, например, emit действительно печатает-проверка сначала путем вызова различных program.getNNNDiagnostics, затем запускает эмиттер с преобразованиями.)

Это может работать или не работать, потому что средство проверки типов изменяет AST, и это зависит от того, находится ли AST в правильном состоянии.

Затем вы можете захотеть взглянуть на API Builder - его цель - следить за изменениями исходного файла и перекомпилировать измененные файлы ( ссылка на исходный код ).Я не знаю, насколько сложно было бы перекомпилировать его при изменениях AST, также похоже, что вы не сможете использовать посетителей, доступных в трансформерах;вам придется обходить AST вручную.

Кроме того, есть библиотека ts-simple-ast , заявленная цель которой - «Предоставить простой способ навигации и манипулирования кодами JavaScript и JavaScript».,Я сам этим не пользовался и понятия не имею, насколько это полезно для вашей цели.

...