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
Add types reference to package.json exports #1184
Conversation
This is an improvement, but still incorrect. Two files (.mjs and .cjs) cannot share a single set of type definitions. See “Types are CJS, but implementation is ESM” in https://github.com/arethetypeswrong/arethetypeswrong.github.io. |
So we should just copy the types into an .mts file? |
@andrewbranch thanks very much for taking a look and for pointing out my mistake! I believe the exported types have been written rather than generated from TS files, so as @dobromir-hristov pointed out would this just be a case of copying and altering the file extension? In what way would the types differ in this instance? |
A copy/paste of the content may or may not result in a valid type declaration file. As you probably know, in Node, imports in ES modules use a different module resolution algorithm from requires in CJS modules. Type declaration files are assumed to be auto-generated, and when they’re generated by tsc, they’re a (near) perfect representation of the corresponding JS. So when a declaration file for a CommonJS module says import { foo } from "./foo" we know the JS looks something like const foo_1 = require("./foo") and we can verify that the module specifier import { foo } from "./foo" And here, we need to verify that the module specifier So you can see that identical content needs to produce two different checking behaviors, and that the content needs to match the runtime JS very closely to avoid false positives. Sometimes, a copy/paste actually works fine (but due to the file extension restriction, it’s usually copying ESM declarations to CJS that’s more likely to work). You can perhaps start with a copy/paste and then run |
Checking The change I've made in this PR, tested using If I build the package, duplicate Whether or not those type definitions are actually correct I do not know. As they are not auto-generated I assume there is no meaningful difference, but that my last solution is just declaring them in the "correct" way? If that's the best solution then I guess it would just be a case of updating the build process to duplicate and rename the type definition file into the |
I checked the existing type declarations manually and can confirm the existing .d.ts looks accurate for both the .mjs and .cjs file. Should be fine to copy/paste like that. Thanks @rdunk! |
Then we need to just add a command to the build I guess? To copy the types with a new name. |
@andrewbranch Really appreciate all your input on this, thanks very much. @dobromir-hristov Yep I believe so, I'm happy to make the change here if you'd like, do you have any preference? Something like rollup-plugin-copy would be simplest but I guess requires an extra dependency, so happy to use a script with |
Also updates other dependencies to be compatible. Includes a patch to @vuelidate/core to get the types correctly. This patch should get removed when vuelidate/vuelidate#1184 is resolved.
Also updates other dependencies to be compatible. Includes a patch to @vuelidate/core to get the types correctly. This patch should get removed when vuelidate/vuelidate#1184 is resolved.
Also updates other dependencies to be compatible. Includes a patch to @vuelidate/core to get the types correctly. This patch should get removed when vuelidate/vuelidate#1184 is resolved.
Also updates other dependencies to be compatible. Includes a patch to @vuelidate/core to get the types correctly. This patch should get removed when vuelidate/vuelidate#1184 is resolved.
Also updates other dependencies to be compatible. Includes a patch to @vuelidate/core to get the types correctly. This patch should get removed when vuelidate/vuelidate#1184 is resolved.
This would definitely be handy for us to merge in, if possible! |
Sorry for the incredibly late reply. A simple copy command could work but ppl on different OS would have issues. Maybe it's better to add a plugin as it's already meant to work everywhere. |
@dobromir-hristov No problem at all. I will add that in and update the PR. |
I've added in a config flag to the |
Looks great. Should we change the exports field? |
packages/vuelidate/package.json
Outdated
@@ -3,7 +3,7 @@ | |||
"description": "Simple, lightweight model-based validation for Vue.js", | |||
"version": "2.0.2", | |||
"main": "dist/index.cjs", | |||
"types": "index.d.ts", | |||
"types": "dist/index.d.cts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could changing the extension break older versions of typescript?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yeah maybe it could... So I looked at the documentation here and just pushed two changes to the package.json
files based on the last example given on that page:
- Reverted
"files"
to include the uncopiedindex.d.ts
file again, and reverted the"types"
field to reference that file. So basically no change to those fields from before this PR. - Updated the
"exports"
field to include the new type declaration files alongside the default import conditions.
I've found this a tad confusing (three identical type declaration files now?) so apologies if I've not got it right again, but arethetypeswrong seems to be happy. Ultimately all this PR now does is copy the type declaration twice, and reference those files in the package.json
"exports"
. So maybe the solution was quite simple after all.
Maybe @andrewbranch can give us a final verification on if this is an OK resolution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, TS versions/configurations that understand exports
(and the newer file extensions) won’t look at this top-level types
field since they’ll look in exports
instead, so it’s best practice to leave the top-level types
as a .d.ts
(as long as you have exports
) for the benefit of old TS versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks for the clarification, that's really helpful to know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
When should we expect a release with this fix? |
@dobromir-hristov would it be possible to get a release with this change? Many thanks 😸 |
Sorry bout that, busy week. Try now. |
❤️ |
Summary
With TS 5.0 introducing "bundler" module resolution (may also apply to "Node16" and "NodeNext", although I haven't tested), importing types from
@vuelidate/core
will result in TS complaining that it can't resolve type declarations. TS seems to find the type declaration file but won't use it because it's not explicitly listed under "exports" inpackage.json
.See this issue for more details: microsoft/TypeScript#52363
This PR just adds a "types" export line to the
package.json
, which seems to keep TS happy and resolve the error.Metadata
What kind of change does this PR introduce? (check at least one)
Does this PR introduce a breaking change? (check one)
If yes, please describe the impact and migration path for existing applications:
The PR fulfills these requirements:
next
branchfix #xxx[,#xxx]
, where "xxx" is the issue number)If adding a new feature, the PR's description includes:
Other information:
N/A