Typescript: Getting resolved import from compiler API

Created on 1 Aug 2017  路  6Comments  路  Source: microsoft/TypeScript

It looks like currently it's not possible to get the path/name of the module that an import statement has been resolved to.

I was able to get the import specifier like "./module" from AST (using https://github.com/dsherret/ts-simple-ast), and from there it would have been easy to retrieve the imported file using SourceFile.resolvedModules, but resolvedModules is marked as @internal.

Specifically, there's these two lines in types.ts:

https://github.com/Microsoft/TypeScript/blob/b74ec1c58b1c01e9331422315a7451d8eaee1ac1/src/compiler/types.ts#L2321-L2322

The comment in the first line references getResolvedModuleFileName/setResolvedModuleFileName but those functions don't seem to exist anywhere in the repo.

API Question

Most helpful comment

@mhegazy @DanielRosenwasser

I also found myself needing access to resolvedModules.

I've got my own TypeScript integrations for node and webpack, each automating some configurations:
https://github.com/AviVahl/ts-tools

My webpack loader needs to know resolved modules per source file, in order to direct webpack to watch them in its graph.

I'd also like to get baseUrl and paths working natively in node/webpack by applying a custom transformer which remaps the imports to the actual target (ignoring relative requests and resolved .d.ts).

EDIT: part below is now fixed on my end. I didn't force moduleResolution: "node" while forcing module: "esnext". That led to TypeScript not being able to resolve modules properly and the undefined. I still expose resolvedModules internal field on SourceFile to access resolutions though.

I've noticed that if I tell TypeScript to transpile to module: 'commonjs', I have the resolvedModules field readily available on the SourceFile filled with the resolution results.

Transpilation to module: 'esnext' is another story. The resolvedModules field is there, but the resolutions point to undefined, so that's not very useful.

I realize this is an internal API, but the work (resolution) has already been done for type checking, so I just need to results exposed. Any chance to get an official API exposing this information? It would cover my use case and simplify many others, like tslint's and other TypeScript integrations.

All 6 comments

It looks like currently it's not possible to get the path/name of the module that an import statement has been resolved to.

Why do you need it for, because it seems like it would be entirely misleading. TypeScript has a very sort of loose concept of module resolution that doesn't necessarily reflect runtime behaviour of module, nor a specific file. For example, this in a .d.ts file would be a resolution of any number of modules imports:

declare module 'text!*' {
    const text: string;
    export = text;
}

So the type location _might_ be useful for quick linking and looking up stuff, but it is a type location, not a resolved file name, nor does it reflect what would actually be done by a module loader at runtime or build time.

Sure, here's my use-case: I'm working on a build tool that offloads modules ending with .ww.ts to a web worker, with a restriction that imports from those .ww.ts files to regular files can only be named imports, and those named imports should be of certain types, to be exact, (...args: any[]): void, Promise<any>, (...args: any[]): Promise<any>, Observable<any>, or (...args: any[]): Observable<any>. So if you have two modules like this:

// moduleA.ww.ts
export const f = () => console.log('f');

```ts
// moduleB.ts
import { f } from './moduleA.ww';
f();

it will generate a main script where moduleA.ww is stubbed out with a file like
```ts
export const f = rpc(...)

and it will also generate a web worker script that imports f from moduleA.ww (that's where I need the actual filename of moduleA.ww) and makes it available to be called through an RPC.

I don't know how clear above explanation is, but hopefully it gives an idea of what I'm trying to do. I'm nearly there, but I had to use a hack where I cast the compiler's SourceFile object to a custom type in order to get at the internal property resolvedModules, and then resolvedModules.get('./moduleA') gives me the filename of moduleA.ww.

@rbuckton may better know how to guide you.

It looks like currently it's not possible to get the path/name of the module that an import statement has been resolved to.
Why do you need it for

Side note, this linter that detects circular imports also needs this information:

https://github.com/bcherny/tslint-no-circular-imports/blob/master/noCircularImportsRule.ts#L34

@mhegazy @DanielRosenwasser

I also found myself needing access to resolvedModules.

I've got my own TypeScript integrations for node and webpack, each automating some configurations:
https://github.com/AviVahl/ts-tools

My webpack loader needs to know resolved modules per source file, in order to direct webpack to watch them in its graph.

I'd also like to get baseUrl and paths working natively in node/webpack by applying a custom transformer which remaps the imports to the actual target (ignoring relative requests and resolved .d.ts).

EDIT: part below is now fixed on my end. I didn't force moduleResolution: "node" while forcing module: "esnext". That led to TypeScript not being able to resolve modules properly and the undefined. I still expose resolvedModules internal field on SourceFile to access resolutions though.

I've noticed that if I tell TypeScript to transpile to module: 'commonjs', I have the resolvedModules field readily available on the SourceFile filled with the resolution results.

Transpilation to module: 'esnext' is another story. The resolvedModules field is there, but the resolutions point to undefined, so that's not very useful.

I realize this is an internal API, but the work (resolution) has already been done for type checking, so I just need to results exposed. Any chance to get an official API exposing this information? It would cover my use case and simplify many others, like tslint's and other TypeScript integrations.

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blendsdk picture blendsdk  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

seanzer picture seanzer  路  3Comments

zhuravlikjb picture zhuravlikjb  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments