TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Cannot find definitions with baseUrl

Open andrewbaxter opened this issue 3 years ago • 3 comments

Bug Report

🔎 Search Terms

typescript "cannot find a declaration file" baseurl typescript "cannot find a declaration file" strace "Could not find a declaration file for module 'marked'" typescript yarn "--modules-folder" typescript cant find definitions baseurl typescript ignores typeroots typescript can't find definitions from @types typescript "cannot find a declaration file for module" typescript "cannot find a declaration file for module" "baseurl"

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about imports

I tried 4.8.3 and typescript@next.

⏯ Playground Link

This is about module path resolution, so a playground link is not helpful.

💻 Code

src/index.ts

import { marked } from "marked";

.yarnrc

--modules-folder ../nm2

tsconfig.json

{
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  "compilerOptions": {
    "lib": ["DOM", "ES2018"],
    "target": "ES2018",
    "downlevelIteration": true,
    "moduleResolution": "Node",
    "strict": true,
    "noImplicitAny": true,
    "baseUrl": "../nm2",
    "typeRoots": ["../nm2/@types"]
  }
}

package.json

{
  "dependencies": {
    "idb": "^7.1.0",
    "marked": "^4.1.0"
  },
  "devDependencies": {
    "@types/marked": "^4.0.7",
    "typescript": "^4.9.0-dev.20220921"
  }
}

I tried with and without typeRoots.

🙁 Actual behavior

The build fails. Running with strace -e openat I see

openat(AT_FDCWD, "my_working_dir.../nm2/typescript/bin/package.json", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/package.json", O_RDONLY|O_CLOEXEC) = 17
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/bin/tsc", O_RDONLY|O_CLOEXEC) = 17
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/tsc.js", O_RDONLY|O_CLOEXEC) = 17
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/package.json", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/pts/34", O_RDWR|O_NOCTTY|O_CLOEXEC) = 17
openat(AT_FDCWD, "/dev/null", O_RDONLY|O_CLOEXEC) = 18
openat(AT_FDCWD, "my_working_dir.../6/tsconfig.json", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../6", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 19
openat(AT_FDCWD, "my_working_dir.../6/src", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 19
openat(AT_FDCWD, "my_working_dir.../6/src/index.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/marked/package.json", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/@types", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/@types/marked/package.json", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/@types/marked/index.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.dom.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2018.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2017.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2016.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es5.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.core.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.collection.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.iterable.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.symbol.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.generator.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.promise.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.proxy.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.reflect.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2015.symbol.wellknown.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2016.array.include.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2017.object.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2017.sharedmemory.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2017.string.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2017.intl.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2017.typedarrays.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2018.asynciterable.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2018.asyncgenerator.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2018.promise.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2018.regexp.d.ts", O_RDONLY|O_CLOEXEC) = 19
openat(AT_FDCWD, "my_working_dir.../nm2/typescript/lib/lib.es2018.intl.d.ts", O_RDONLY|O_CLOEXEC) = 19
src/index.ts:1:24 - error TS7016: Could not find a declaration file for module 'marked'. 'my_working_dir.../nm2/marked/lib/marked.cjs' implicitly has an 'any' type.
  Try `npm i --save-dev @types/marked` if it exists or add a new declaration (.d.ts) file containing `declare module 'marked';`

1 import { marked } from "marked";
                         ~~~~~~~~


Found 1 error.

+++ exited with 1 +++

6 is the directory with tsconfig.json.

Note that it actually finds and opens the marked definitions file above.

🙂 Expected behavior

It should compile fine.

Copying nm2 to node_modules in the tsconfig.json dir allows it to compile, it opens files in node_modules right after marked/package.json.

Another package, idb works fine (replacing the marked import with idb). idb has its own typings.

With typeRoots removed, it doesn't open any files in nm2/@types.

Tangentially, if nm2 is in the current directory (not the parent directory) I get the above error plus tons of Definitions of the following identifiers conflict with those in another file regarding various typescript internal symbols.

I get the feeling that typescript requires modules to be in node_modules, but I couldn't find anything in the documentation that suggests this so I continue to cling to hope.

Edit: Forgot package.json

andrewbaxter avatar Sep 21 '22 13:09 andrewbaxter

I get the feeling that typescript requires modules to be in node_module

You specified moduleResolution: node in the tsconfig, and node requires modules to be in node_modules.

For this scenario, you'd need to use path mapping.

RyanCavanaugh avatar Sep 21 '22 23:09 RyanCavanaugh

Firstly, thank you for looking into this!

That doesn't make a lot of sense to me, the documentation clearly states

All module imports with non-relative names are assumed to be relative to the baseUrl.

not relative to node_modules directly underneath baseUrl. There's no additional notes regarding baseUrl in either the Node nor Classic sections.

Furthermore it's locating the JS marked package, just not the typings (which are a TypeScript specific thing anyway, especially the @types directory, so I wouldn't expect that to be affected module resolutions).

After digging some more I found the --traceResolution flag and have some more output (here's the full output):

======== Resolving module 'marked' from 'MY_PARENT_DIR/6/src/index.ts'. ========
Explicitly specified module resolution kind: 'NodeJs'.
'baseUrl' option is set to 'MY_PARENT_DIR/nm2', using this value to resolve non-relative module name 'marked'.
Resolving module name 'marked' relative to base url 'MY_PARENT_DIR/nm2' - 'MY_PARENT_DIR/nm2/marked'.
Loading module as file / folder, candidate module location 'MY_PARENT_DIR/nm2/marked', target file type 'TypeScript'.
File 'MY_PARENT_DIR/nm2/marked.ts' does not exist.
File 'MY_PARENT_DIR/nm2/marked.tsx' does not exist.
File 'MY_PARENT_DIR/nm2/marked.d.ts' does not exist.
Found 'package.json' at 'MY_PARENT_DIR/nm2/marked/package.json'.
'package.json' does not have a 'typesVersions' field.
'package.json' does not have a 'typings' field.
'package.json' does not have a 'types' field.
'package.json' has 'main' field './lib/marked.cjs' that references 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs'.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' exist - use it as a name resolution result.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' has an unsupported extension, so skipping it.
Loading module as file / folder, candidate module location 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs', target file type 'TypeScript'.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs.ts' does not exist.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs.tsx' does not exist.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs.d.ts' does not exist.
File name 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' has a '.cjs' extension - stripping it.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cts' does not exist.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.d.cts' does not exist.
Directory 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' does not exist, skipping all lookups in it.
File 'MY_PARENT_DIR/nm2/marked/index.ts' does not exist.
File 'MY_PARENT_DIR/nm2/marked/index.tsx' does not exist.
File 'MY_PARENT_DIR/nm2/marked/index.d.ts' does not exist.
Loading module 'marked' from 'node_modules' folder, target file type 'TypeScript'.
Directory 'MY_PARENT_DIR/6/src/node_modules' does not exist, skipping all lookups in it.
Directory 'MY_PARENT_DIR/6/node_modules' does not exist, skipping all lookups in it.
Directory 'MY_PARENT_DIR/node_modules' does not exist, skipping all lookups in it.
Directory 'MY_PARENT_DIR^1/node_modules' does not exist, skipping all lookups in it.
File 'MY_PARENT_DIR^2/node_modules/marked.ts' does not exist.
File 'MY_PARENT_DIR^2/node_modules/marked.tsx' does not exist.
File 'MY_PARENT_DIR^2/node_modules/marked.d.ts' does not exist.
Directory 'MY_PARENT_DIR^2/node_modules/@types' does not exist, skipping all lookups in it.
Directory 'MY_PARENT_DIR^3/node_modules' does not exist, skipping all lookups in it.
Directory '/home/node_modules' does not exist, skipping all lookups in it.
Directory '/node_modules' does not exist, skipping all lookups in it.
'baseUrl' option is set to 'MY_PARENT_DIR/nm2', using this value to resolve non-relative module name 'marked'.
Resolving module name 'marked' relative to base url 'MY_PARENT_DIR/nm2' - 'MY_PARENT_DIR/nm2/marked'.
Loading module as file / folder, candidate module location 'MY_PARENT_DIR/nm2/marked', target file type 'JavaScript'.
File 'MY_PARENT_DIR/nm2/marked.js' does not exist.
File 'MY_PARENT_DIR/nm2/marked.jsx' does not exist.
File 'MY_PARENT_DIR/nm2/marked/package.json' exists according to earlier cached lookups.
'package.json' has 'main' field './lib/marked.cjs' that references 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs'.
File 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' exist - use it as a name resolution result.
======== Module name 'marked' was successfully resolved to 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' with Package ID 'marked/lib/[email protected]'. ========
======== Resolving type reference directive 'marked', containing file 'MY_PARENT_DIR/6/__inferred type names__.ts', root directory 'MY_PARENT_DIR/nm2/@types'. ========
Resolving with primary search path 'MY_PARENT_DIR/nm2/@types'.
Found 'package.json' at 'MY_PARENT_DIR/nm2/@types/marked/package.json'.
'package.json' does not have a 'typesVersions' field.
'package.json' does not have a 'typings' field.
'package.json' has 'types' field 'index.d.ts' that references 'MY_PARENT_DIR/nm2/@types/marked/index.d.ts'.
File 'MY_PARENT_DIR/nm2/@types/marked/index.d.ts' exist - use it as a name resolution result.
Resolving real path for 'MY_PARENT_DIR/nm2/@types/marked/index.d.ts', result 'MY_PARENT_DIR/nm2/@types/marked/index.d.ts'.
======== Type reference directive 'marked' was successfully resolved to 'MY_PARENT_DIR/nm2/@types/marked/index.d.ts' with Package ID '@types/marked/[email protected]', primary: true. ========
src/index.ts:2:24 - error TS7016: Could not find a declaration file for module 'marked'. 'MY_PARENT_DIR/nm2/marked/lib/marked.cjs' implicitly has an 'any' type.
  Try `npm i --save-dev @types/marked` if it exists or add a new declaration (.d.ts) file containing `declare module 'marked';`

2 import { marked } from "marked";
                         ~~~~~~~~


Found 1 error.

This is strange, since it's clearly identifying the typings file here:

======== Type reference directive 'marked' was successfully resolved to 'MY_PARENT_DIR/nm2/@types/marked/index.d.ts' with Package ID '@types/marked/[email protected]', primary: true. ========

This was with baseUrl and typeRoots provided as above.

andrewbaxter avatar Sep 22 '22 02:09 andrewbaxter

It's not clear to me how paths would resolve this or how it could be used. My reading from the documentation is that it's a way to override the lookup for specific individual packages in odd locations (and it's not indicated in the documentation if/how this affects type lookups). If so this would be a nonstandard use of the parameter in a non-intuitive way.

I tried:

"paths": {
	"*": ["*"]
}

in addition to the above config. This didn't work (found js, not types), and looks pointless (i.e. look where you're already looking).

I also tried

"paths": {
	"*": ["../nm2/*"]
}

without baseUrl or typeRoots and that also failed (same as above - located js, not types).

andrewbaxter avatar Sep 22 '22 02:09 andrewbaxter

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 or the TypeScript Discord community.

typescript-bot avatar Sep 24 '22 12:09 typescript-bot