question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

foo.ts is resolved before foo.d.ts even if the latter is in files[]

See original GitHub issue

Affects at least TS 2.7.2 and 2.6.2. This problem appears when compiling files separately, like we do under Bazel.

Imagine this simple app

src/lib.ts

export const a = 1;

src/main.ts

import {a} from './lib';

Imagine lib.ts was compiled separately, so there already exists dist/lib.d.ts

export declare const a = 1;

Now, I want to compile main.ts as a separate program. Given src/tsconfig.json

{
  "compilerOptions": {
    "rootDirs": [
      ".",
      "../dist"
    ],
    "outDir": "../dist",
    "declaration": true
  },

  "files": [
    "main.ts",
    // lib was compiled separately
    "../dist/lib.d.ts"
  ]
}

We see that lib.d.ts is already in the program before resolution begins. However the compiler resolves the import statement to the lib.ts file instead, adding it to the program, and tries to emit on top of an input, so the error is

$ ./node_modules/.bin/tsc -p src
error TS5055: Cannot write file '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/dist/lib.d.ts' because it would overwrite input file.

Okay, we didn’t want lib.ts in the program, so we should just use --noResolve to prevent that, but it’s also broken:

$ ./node_modules/.bin/tsc -p src --noResolve --traceResolution
======== Resolving module './lib' from '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/main.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
'rootDirs' option is set, using it to resolve relative module name './lib'.
Checking if '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/' is the longest matching prefix for '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib' - 'true'.
Checking if '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/dist/' is the longest matching prefix for '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib' - 'false'.
Longest matching prefix for '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib' is '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/'.
Loading 'lib' from the root dir '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/', candidate location '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib'.
Loading module as file / folder, candidate module location '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib', target file type 'TypeScript'.
File '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib.ts' exist - use it as a name resolution result.
======== Module name './lib' was successfully resolved to '/usr/local/google/home/alexeagle/Projects/repro_ts_resolving_ts/src/lib.ts'. ========
src/main.ts(1,17): error TS2307: Cannot find module './lib'.

So far our workaround at Google is one of:

  • use Bazel sandboxing to make the inputs appear in different places
  • use our own custom compiler which elides any emit to files we don’t expect

However under Bazel we sometimes cannot sandbox (eg. on Windows) and cannot use our custom compiler (eg. when we are compiling it) so we are stuck.

I found that ts.CompilerOptions.suppressOutputPathCheck could be a workaround, but tsc doesn’t allow that flag from the command line or tsconfig.json (it’s not in optionDeclarations in commandLineParser.ts)

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

5reactions
mprobstcommented, Mar 28, 2018

Alternative idea: when --noResolve is true, just never look at the file system and only use the list of source files as the source of truth on what files are present? Then in the example above, ../dist/lib.ts would consistently not be found, and compilation would succeed by finding lib.d.ts (or fail if that’s not around).

2reactions
alexeaglecommented, Mar 1, 2018

I think the way to fix this is not to always try to resolve imports using other rootDirs, only to check if the rootFiles already satisfy an import.

Read more comments on GitHub >

github_iconTop Results From Across the Web

File 'app/hero.ts' is not a module error in the console, where to ...
Try Restarting the editor in which you are writing the code(VS code or Sublime). Compile and Run it again. I have done the...
Read more >
Documentation - Modules .d.ts - TypeScript
One style of exporting in CommonJS is to export a function. Because a function is also an object, then extra fields can be...
Read more >
Router tutorial: tour of heroes - Angular
This tutorial provides an extensive overview of the Angular router. In this tutorial, you build upon a basic router configuration to explore features...
Read more >
IO tools (text, CSV, HDF5, …) — pandas 1.5.2 documentation
If {'foo': [1, 3]} -> parse columns 1, 3 as date and call result 'foo'. ... function works with data files that have...
Read more >
Content Types - ESBuild
d.ts files) is not supported. If you are writing a library in TypeScript and you want to publish the compiled JavaScript code as...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found