New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSDoc types.js cannot be used for package-level and export-level types #50436
Comments
Complete Reduced Test CaseHere's a reduced test case with all the https://github.com/coolaj86/test-case-tsc-exports .
├── README.md
├── main.js
├── tsconfig.json
└── node_modules
├── bar
│ ├── bar.js
│ ├── package.json
│ ├── tsconfig.json
│ └── types.js
└── foo
├── foo.js
├── package.json
├── tsconfig.json
└── types.js
|
There’s no such thing as “package scope,” perhaps unfortunately. There are only two ways to access things cross-file: (1) accessing a global, or (2) importing an export. In any TypeScript or JavaScript file under default compiler options, files that don’t contain any imports or exports (or
So in fact, everything everywhere in the program, not just in the package, can access the type declared in In your next permutation:
So again, packages have nothing to do with it. When you add export syntax to While your expected behavior would definitely be convenient, there’s just no concept of scoping like that for JavaScript values (e.g. I can’t declare a variable that is automatically accessible in every file in package |
Well, node's been around a lot longer that TypeScript, and TypeScript is built for node, so one would reasonably expect that TypeScript as a super-duper JavaScript linter would know to keep the boundaries around package.json Nevertheless, thanks for the detailed answer. 🙂 Hmmm... dangit. JSDoc + TypeScript has so many edge cases and bugs / working-as-intendeds-but-still-actually-bugs... We need a super-duper-linter + type-checker for JavaScript that really, really gets JavaScript. 🤷♂️ I'll just go fix it the easy way... 😕🔫 |
Could I perhaps convert this to a feature request? |
I hoped that my answer would imply that such a feature would be an architecturally heavy lift, and likewise not actually desirable in terms of maintaining an explainable mental model of scoping. I said that your expected behavior would be convenient, because at first glance it would certainly save you some keystrokes. But we really like that scoping and module rules are equivalent for types and values, because you only have to learn one set of rules, and those rules aren’t even specific to TypeScript. Globals are globals, exports are exports. The confusing part, in my opinion, is that JSDoc declarations automatically become exports as soon as the file becomes a module. Also, from experience, I have found that most people don’t assume that their files are global scripts just because they don’t currently have any imports or exports. For that, we have the That said, global access to your types in JS is pretty nice, since the syntax to import them is cumbersome. My advice for JS projects that aren’t libraries shipping to npm: define your types as globals in a // types.d.ts
namespace mypackage {
export interface Foo {
x: string;
}
}
// index.js
/** @param {mypackage.Foo} foo */
function f(foo) {} |
I don't do implied. Not one of my brain functions.
Yes, very confusing. To a lot of people (everyone I've been asking about this on Twitter, Slack, StackOverflow, in the office, at least).
Does this mean that when you import them from another JavaScript project that it will also have to use the namespace? /** @typedef {import('mypackage').mypackage.Foo} Foo */ Or are the namespaces global as well? |
I don't see this in the comments for a default |
The namespace is global if the stuff in the file is global, which is dependent upon
No, not every tsconfig option shows up in the |
Bug Report
🔎 Search Terms
JSDoc exports package scope
🕗 Version & Regression Information
⏯ Playground Link
N/A This occurs between multiple files, not in single file.
💻 Code
Problem
Catch 22:
If I don't include
export default {}
(ormodule.exports = {}
) then I can't import the types from another module.If I do include the export, then files within the packages no longer have package-scope access to the types.
I've also opened a question looking for a workaround on StackOverflow:
https://stackoverflow.com/questions/73480632/how-can-i-export-package-scope-jsdoc-types
Example A: Can't import 'Foo' types from package 'Bar'
Everything within the package itself can access its own types just fine - but they can't be exported.
✅
node_modules/foo/index.js
:node_modules/foo/types.js
(injsconfig.json.includes
):❌
bar.js
:Example B: Can't access 'Foo' types from package 'Foo'
Now external packages have access to
Foo
, but theFoo
package itself can't access it.❌
node_modules/foo/index.js
:node_modules/foo/types.js
(injsconfig.json.includes
):✅
bar.js
:Now
bar.js
can find the typeFoo
without issue.🙁 Actual behavior
🙂 Expected behavior
Foo
Foo
Having one shouldn't break the other.
The text was updated successfully, but these errors were encountered: