-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Description
TypeScript Version: 4.0.0-dev.20200725 8000 and 3.9.7
Search Terms:
declaration files path mapping import extension
Code
Multiple files are needed to reproduce this. Filenames as first comment:
// node_modules/foo/lib/test.d.ts
export declare function test(): void;
// node_modules/foo/lib/test.js
export function test() {
console.log("test");
}
// src/test.ts
import { test } from "foo/test.js";
test();
// tsconfig.json
{
"compilerOptions": {
"rootDir": "src",
"outDir": "lib",
"target": "ES6",
"module": "ES6",
"baseUrl": ".",
"moduleResolution": "Node",
"noImplicitAny": true,
"paths": {
"foo/*": [ "node_modules/foo/lib/*" ]
}
}
}
The noImplicitAny
option is set here so the compiler actually complains about the missing type information when it can't find the typings of foo/test.js
.
Expected behavior:
Running tsc
should compile the project. The import of foo/test.js
should be resolved to node_modules/foo/lib/test.js
because of the path mapping (Which works) and it should read the typings from node_modules/foo/lib/test.d.ts
(Which doesn't work).
Actual behavior:
When running tsc --traceResolution
I get this error message:
/tmp/test$ tsc --traceResolution
======== Resolving module 'foo/test.js' from '/tmp/test/src/test.ts'. ========
Explicitly specified module resolution kind: 'NodeJs'.
'baseUrl' option is set to '/tmp/test', using this value to resolve non-relative module name 'foo/test.js'.
'paths' option is specified, looking for a pattern to match module name 'foo/test.js'.
Module name 'foo/test.js', matched pattern 'foo/*'.
Trying substitution 'node_modules/foo/lib/*', candidate module location: 'node_modules/foo/lib/test.js'.
File '/tmp/test/node_modules/foo/lib/test.js' exist - use it as a name resolution result.
======== Module name 'foo/test.js' was successfully resolved to '/tmp/test/node_modules/foo/lib/test.js'. ========
src/test.ts:2:22 - error TS7016: Could not find a declaration file for module 'foo/test.js'. '/tmp/test/node_modules/foo/lib/test.js' implicitly has an 'any' type.
2 import { test } from "foo/test.js";
~~~~~~~~~~~~~
Found 1 error.
And now comes the interesting part. When you strip the extension from the import and use "foo/test"
instead of "foo/test.js"
then it works. But unfortunately this isn't an option because then the generated JavaScript does not work in Node.js which requires a *.js extension for ES modules.
It also works when removing the path mapping and using "foo/lib/test.js"
as import.
So using import file extension alone works, using path mapping alone works, too. But using both together fails.