Как я могу использовать API компилятора TS, чтобы узнать, изменились ли типы в .d.ts?

Я хотел бы иметь возможность узнать, изменились ли типы в файле объявления TypeScript с момента последней компиляции. Некоторые ложные срабатывания допустимы (говорят, что типы изменились, когда они этого не сделали), но нельзя сказать, что ничего не изменилось, когда что-то изменилось.

Для .d.ts без импорта я мог бы провести сравнение строк между старым .dts и новым .d.ts.

Но когда у .d.ts есть импорт, его значение может зависеть от того, что находится в других файлах:

import { OtherType } from "./other"
export type Wrapped = { other: OtherType }

В этом случае я мог бы выполнить рекурсию и сериализовать Wrapped, а затем сравнить сериализованные представления. Но с рекурсивными типами все усложняется.

Для номинальных типов, я думаю, мне придется соотнести NodeIds или что-то в этом роде.

Есть ли что-то в API компилятора TS, что уже делает это, или альтернативный подход к решению проблемы?


person Max Heiber    schedule 30.11.2019    source источник


Ответы (1)


Я считаю, что наиболее эффективный способ сделать это - работать только с AST. Таким образом, вместо различий на основе текста вы можете выполнить «семантическое различие», в котором вы анализируете AST, используя ts.createSourceFile, проходите узлы, используя ts.forEachChild, создавая свою собственную структуру, подобную таблице символов, как для старого, так и для нового файлов объявлений, а затем сравнивайте структуры на предмет различий. . В зависимости от степени реализации это может привести к некоторым ложным срабатываниям, и вам нужно будет дать ему понять, как следовать спецификаторам модуля декларации импорта и экспорта для других файлов.

Альтернативный подход - использовать средство проверки типов и получить символ обоих исходных файлов (const fileSymbol = typeChecker.getSymbolAtLocation(sourceFile);). Оттуда вы можете сравнить ключи в свойстве exports, а затем перейти от значений к объявлениям (например, см. этот ответ).

В любом случае, это ответ довольно высокого уровня. Дайте мне знать, если вы хотите, чтобы я более подробно остановился на чем-либо. То, что вы делаете, - это инструмент, ожидающий создания (например, проверка файла декларации на наличие критических изменений).

person David Sherret    schedule 02.12.2019
comment
Думаю, описанные вами подходы сработают, спасибо за ответ! Похоже, что может быть больше поддержки для такого рода вещей в восходящем направлении (в API компилятора TS), поскольку лучшие подходы, которые мы можем придумать, приводят к множеству ложных срабатываний. - person Max Heiber; 06.12.2019