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

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

У меня такой код:

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

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

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


person Jason Kuhrt    schedule 09.11.2020    source источник
comment
Для любопытных: контекст этого вопроса проистекает из github.com/jasonkuhrt/tydoc/issues/41..   -  person Jason Kuhrt    schedule 09.11.2020


Ответы (1)


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

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

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

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

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

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

person David Sherret    schedule 09.11.2020
comment
Спасибо! Я следил за проблемой GitHub TS. Спасибо за все ссылки. Я очень ценю это!! - person Jason Kuhrt; 09.11.2020