Skip to content
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

feat: produce TS declaration files #317

Closed
wants to merge 1 commit into from
Closed

Conversation

SimenB
Copy link

@SimenB SimenB commented Jun 1, 2022

This allows consumers not to set allowJs and maxNodeModuleJsDepth in order to consume the types

@jaydenseric
Copy link
Owner

Thanks for your interest in contributing to the project!

For a long time (over a year) I investigated the best possible way to add type safety to all my packages that works universally in Node.js TypeScript projects as well as Deno projects, without a build step. I consciously decided generating type definition files was not part of the solution, for reasons (briefly) explained here:

#282 (comment)

JavaScript modules containing TypeScript JSDoc comment based types are incredibly portable. Deno users can import them from almost any CDN and enjoy the types without doing anything special, and it's really easy for Node.js TypeScript users to tweak their TypeScript config to get a similar experience.

@jaydenseric jaydenseric closed this Jun 1, 2022
@SimenB
Copy link
Author

SimenB commented Jun 1, 2022

The "build step" is already in the repo and part of your prepublishOnly script, you just don't keep any artifacts from it. So this doesn't add any new steps or require a single change to your flow.

Requiring users to change away from the default tsconfig just to consume your library seems an unnecessary complication. Especially when you don't even wanna document it. It working out of the box for Deno is great, but that shouldn't be used as a reason not to work out of the box with Node and TypeScript, which has orders of magnitudes more users.

@jaydenseric
Copy link
Owner

The situation is more nuanced than you may realise. For example, what happens when a Deno user imports a module from a package that has both JSDoc types and type definitions (like proposed by this PR) via a CDN like esm.sh, that detects there are type definition files, does a bunch of work to resolve and build Deno friendly type definition files for that version of the package if it is not yet built, and then adds them in the response in a X-TypeScript-Types header? I'm pretty sure a loading/caching waterfall event will happen where Deno will then go out and fetch the definition files, and any other definitions that definition imports, and so forth, and cache them all to disk, redundantly when it had the JSDoc types available in the original module's response all along it could have used.

There are more things to consider I haven't even mentioned yet. For example, when using JSDoc based types command clicking on them in your project code opens the actual module you are using them from and takes you to the right place, instead of opening some definition file that is missing all of the context the actual implementation code gives you. If we added definition files on top of the JSDoc comments, we would lose that DX.

The way my package types script currently works is not a build step; it doesn't emit any files and is not necessary to run while developing the package. It's a type check script for CI, in the same way that Prettier or ESLint scripts are not build scripts but check scripts. The proposed changes in this PR introduce a build step; you are generating and not manually authoring those type definition files that get published.

@iainjreid
Copy link

For a long time (over a year) I investigated the best possible way to add type safety to all my packages

Silver bullets are rare, and in this instance I feel the sheer number of TS related comments in many of the projects issues regarding the types (not) exported by this package, tells the true story.

JSDoc is a documentation tool, a great one, but it's only that. It can't handle complex generic types, higher kinded types, conditional types, type narrowing, I could go on; ergo, choosing it as the single option to document all of your packages seems a little ambitious.

I've been down this road before with many small packages, and have almost always ended up following the popular maintainers approach of writing JS and "hand crafting" TSD files on the side. They sit right next to the files that they describe (avoiding the issue of context that you rightly mentioned), and do a much better job describing the type level information than JSDoc could ever do on its own.

This approach requires no tooling, no extra build steps, is easy to maintain, and future proofs your project in the event that you require any features that JSDoc simply cannot handle.

I'm seeing this package bundled in with many Apollo codebases these days, and I really think that they would all benefit from either this PR, or a straight up rewrite of the types as raw TSD files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants