I'm looking for a workaround for this bug in tsc: https://github.com/microsoft/TypeScript/issues/50436
Problem 1:
Package-scoped types are not available outside of a package.
- If you declare a type in
./types.js(and include that file injsconfig.json.includethen that type is scoped to your package - any file can use it. Example:// types.js /** * @typedef {Object} Foo * @prop {String} name */ // index.js /** @type {Foo} */ let foo; - You cannot import that type from another package. Example:
// bar.js /** @type {import('foo/types.js').Foo} */ let foo; // ❌ [tsserver] Cannot find name 'Foo'.
Problem 2
Exported types are not available in the package-scope.
- If you add an export to
./types.js, the types are no longer available at the package level. Example:// types.js module.exports = {}; // causes types to be exported /** * @typedef {Object} Foo * @prop {String} name */ // index.js /** @type {Foo} */ let foo; // ❌ [tsserver] Cannot find name 'Foo'. - But now import that type from another package. Example:
// bar.js /** @type {import('foo/types.js').Foo} */ let foo;
Reduced Test Case Git Repo
Here's a reduced test case with all the tsconfig.json, package.json, etc:
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
Catch 22
How can I both export types and have them available in the package scope?
The thing is that
foo/types.jsis declaring a global type only accessible in the package it's declared in. This is becausefoo/types.jsis not a module so everything becomes global inside it. From the docs:To fix the problem then both
foo/types.jsandbar/types.jsshould have an export likemodule.exports = {};(or the one you've written inbar/types.jsor even ES modules likeexport {}).The following are the
types.jsfiles:bar/types.js
foo/types.js
And to use the type in the package level it must be the same way it is in Typescript, just importing it. This way everything should work as expected.
bar/bar.js
foo/foo.js
main.js
Here's the repo with the fixes inplace: https://github.com/lepsch/test-case-tsc-exports