учитывая:
// foo.ts
import { bar } from "./bar"
// bar.ts
export const bar = 3;
Если у меня есть ts.Symbol
для bar
в "foo.ts", как я могу получить bar
в "bar.ts"?
В идеале API компилятора TS должен представлять цепочку использования-определения, которую я могу пройти, чтобы найти определение. Я не думаю, что это так.
Так что теперь я пытаюсь:
- использовать спецификатор модуля "./bar.ts" и текущий
ts.SourceFile
чтобы получить ts.ResolvedModule
объект, представляющий "bar.ts", который содержит полный путь к файлу. - Do
ts.SourceFile(fullFilePath)
чтобы получить ts.SourceFile
для "bar.ts" - Do
checker.getExportsOfModule(symbolForBarDotTs)
, чтобы получить экспорт из "bar.ts" и найти файл с подходящим именем.
Сложная часть, похоже, разрешает модуль из спецификатора модуля. Я не хочу писать logi c для разрешения модулей с нуля, потому что алгоритм сложен и зависит от взаимодействия как минимум шести опций компилятора. Две части API компилятора TS казались многообещающими:
host.resolveModuleNames
, который, к сожалению, доступен только в том случае, если хост реализовал его, а хост компилятора по умолчанию не реализует его. - используйте
(program.getSourceFile(pathToFoo) as any).resolvedModules
. Свойство resolvedModules
, кажется, имеет именно то, что я ищу, но не является частью API publi c.
Есть ли лучший способ? Я надеюсь:
В этом случае легко увидеть, что" ./bar "относится к смежному исходному файлу в файловой системе с соответствующим именем, но когда кто-то использует "paths" или "node_modules" или "@types", et c. тогда разрешение модуля нетривиально.
Обновление
По общему вопросу:
Если у меня есть ts.Symbol
для bar
in " foo.ts ", как мне добраться до bar
в" bar.ts "?
@ Ответ DavidSherret будет работать большую часть времени.
Однако он не выполняет то, что мне нужно, в следующем случае:
// foo.ts
import { bar } from "./bar"
// bar.ts
export { bar } from "./baz"
// baz.ts
export const bar = 3;
TypeChecker # getAliasedSymbol говорит, что baz
в "foo.ts" указывает на bar
в " baz.ts ", пропуская" bar.ts "целиком. Это не сработало для моих целей, потому что я пытаюсь выяснить, учитывая набор точек входа, какие части файлов .d.ts больше не нужны, и удалить ненужные части. В этом случае было бы плохой идеей удалить "bar.ts".