Используйте API компилятора TypeScript для получения узла объявления псевдонима типа из узла ссылки на тип

#typescript #tsc #typescript-compiler-api

#typescript #tsc #typescript-compiler-api

Вопрос:

Я работаю с ts-morph, который, в свою очередь, использует API компилятора TS.

У меня есть этот пример кода:

 export type Foo = string
export const foo: Foo = 'bar'
  

Когда я ищу тип для экспорта foo , я получаю string . Но на самом деле мне нужен тип объявления псевдонима типа.

Тип узла foo экспорта — это VariableDeclaration . Оттуда я понял, как добраться до TypeReferenceNode . Оттуда у меня есть способ получить имя ссылки. В этом случае "Foo" . Но я не знаю, как теперь перейти от этого имени к объявлению псевдонима типа. Предположим, мы не знаем местоположение "Foo" псевдонима типа. Как определить это динамически?

Комментарии:

1. Для любопытных контекст этого вопроса проистекает из github.com/jasonkuhrt/tydoc/issues/41 .

Ответ №1:

В данной конкретной ситуации это невозможно. Компилятор TypeScript использует определенные типы по соображениям производительности.

По соображениям производительности мы внедряем типы, где это возможно (таким образом, мы избегаем дублирования работы для эквивалентных типов). В настоящее время мы не используем анонимные типы объектов, хотя мы экспериментировали с этим раньше. К сожалению, интернирование типов объектов имеет побочный эффект нарушения перехода к определению интернированных типов; поэтому мы не включили его. Конкретные типы, которые мы изучаем сегодня, — это индексированные обращения, объединения и пересечения (также обратные отображаемые типы, но их может создавать только вывод). Это компромисс — информация о происхождении теряется при интернированных типах; но большую часть времени мы избегаем довольно большой работы. — Источник

Итак, здесь Foo интернируется, string поскольку они эквивалентны. Я спросил в репозитории TypeScript, возможно ли отключить это поведение по соображениям анализа, но пока не получил ответа.

Один трюк, который вы можете сделать, чтобы заставить это работать, — изменить код, чтобы использовать бренд вместо only string .

 export type Foo = string amp; { __FooBrand?: undefined };
export const foo: Foo = 'bar';
  

Дополнительные ссылки:

Комментарии:

1. Спасибо! Я проследил за проблемой TS на GitHub. Спасибо за все ссылки. Я действительно ценю это!!