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

How to have a single source of truth for types and docs? #499

Open
LeaVerou opened this issue Mar 28, 2024 · 11 comments · May be fixed by #528
Open

How to have a single source of truth for types and docs? #499

LeaVerou opened this issue Mar 28, 2024 · 11 comments · May be fixed by #528
Labels
Topic: Documentation Improvements or additions to documentation
Milestone

Comments

@LeaVerou
Copy link
Member

This came out of the discussion in #496

Currently, we are generating typedoc API docs from the .d.ts files. However, the actual descriptions of API parameters live in the source .js files. If we point typedoc to the .js files we lose the types, if we point it to the TS files, we lose the descriptions. That's pretty much the definition of "stuck between a rock and hard place", both of these are TERRIBLE. 😢

I think it should be top priority to fix this.

Solutions:

Solution 1: We bite the bullet and move to our source to TypeScript

Pros:

  • One place for docs and types, no more having to keep separate .d.ts files in sync, simpler directory structure.
  • Most straightforward way to solve the problem.

Cons:

  • Higher bar for contributions (many color scientists can fudge together some JS, but TS can be impenetrable to someone who is not a professional front-end developer)
  • No longer possible to make even the smallest edit without running build tools (currently we can get away with just running them before releases)

Solution 2: Moving all types to JSDoc, generating .d.ts files from that

These days, .d.ts files can be generated from JSDoc, though then you're bound by what JSDoc can do, and there is a lot it cannot do, or is painful (e.g. imported types).

I don't have a good sense of what this would involve, whether it would be feasible, and how painful it might be. @jgerigmeyer @MysteryBlokHed you've worked with our types the most, what do you think?

Solution 3: Using JSDoc’s @inheritdoc directive?

@MysteryBlokHed mentioned this, no idea how it can help us, perhaps they can investigate?


Any other ideas?

Pinging all core maintainers @svgeesus @jgerigmeyer @MysteryBlokHed @facelessuser

@LeaVerou LeaVerou added the Topic: Documentation Improvements or additions to documentation label Mar 28, 2024
@MysteryBlokHed
Copy link
Member

We could also use a mix of .d.ts files and JSDoc. Some other projects will document all their exported members (classes, functions, etc) in code, and then use a TypeScript file exclusively to define types (like interfaces).

@LeaVerou
Copy link
Member Author

We could also use a mix of .d.ts files and JSDoc. Some other projects will document all their exported members (classes, functions, etc) in code, and then use a TypeScript file exclusively to define types (like interfaces).

That is what we're currently doing, but it seems impossible to get typedoc to read both? We can't be forced to pick between having API docs for types and having API docs for descriptions!

@MysteryBlokHed
Copy link
Member

We could also use a mix of .d.ts files and JSDoc. Some other projects will document all their exported members (classes, functions, etc) in code, and then use a TypeScript file exclusively to define types (like interfaces).

That is what we're currently doing, but it seems impossible to get typedoc to read both? We can't be forced to pick between having API docs for types and having API docs for descriptions!

I just mean that we could migrate all of our documentation and typing for functions/classes to the source, then point TypeDoc at those files instead. The .d.ts files would just declare interfaces instead of documenting the actual API.

So JSDoc in the source would look more like this:

/**
 * Some function
 * @param {Color} color Type declared in curly brackets
 * @returns {Color}
 */

And then .d.ts files would export only types and interfaces.

@MysteryBlokHed
Copy link
Member

I know that Svelte is one repository that uses this approach. Here’s a source folder where you can see what they do: https://github.com/sveltejs/svelte/tree/main/packages/svelte/src/store

The documentation for functions are kept with the JS files, while types and interfaces are exported with the .d.ts files.

@MysteryBlokHed
Copy link
Member

One consideration I just realized: I’m not sure how to do function overloads in JSDoc alone (or whether it’s actually possible to). There are a good few functions in Color.js that work that way, so it’s important to make sure that they’re properly documented

@jgerigmeyer
Copy link
Collaborator

jgerigmeyer commented Mar 28, 2024

I'm just heading out for 10 days of time off so won't be able to contribute to this in the short term, but I don't currently see a workable solution beyond either 1) live with docs in both places and try to be clear about what type of documentation to put where (i.e. what @MysteryBlokHed described here), or 2) convert the source to TypeScript.

I appreciate the downsides that @LeaVerou outlined (although I'm not sure an extra build step would be necessary on every commit if we don't include transpiled JS files in the repo), but my personal preference would be to move the source to TypeScript (and this is something I'm willing to help do). The main benefit I see is that I'm confident it would reveal some already-existing bugs and inconsistencies in the source, where we're being inconsistent about arg/return types etc. It also ensures our types are accurate and up-to-date, whereas otherwise that's a manual process we need to remember for every change to the source.

@lloydk
Copy link
Collaborator

lloydk commented Mar 28, 2024

I think the majority (all?) of the function oriented API could be documented properly using the Svelte technique that @MysteryBlokHed pointed to. The dynamic nature of the object oriented API makes it more difficult to document.

I haven't tried this but I think overloaded functions can be documented using @overload. Svelte does that here

@MysteryBlokHed
Copy link
Member

I haven't tried this but I think overloaded functions can be documented using @overload. Svelte does that here

Neat, I've never seen the @overload directive before! I don't see any issue with moving over to JSDoc types then, assuming everyone else is on board. It feels like the most intuitive way to keep docs with the actual implementation (besides outright switching to TypeScript, which has its own cons).

@MysteryBlokHed
Copy link
Member

If nobody objects, then I can start looking into switching the library to JSDoc types where possible, with .d.ts elsewhere (eg. for the auto-generated space accessor types)

@LeaVerou
Copy link
Member Author

That would be wonderful, thanks so much @MysteryBlokHed!

@MysteryBlokHed
Copy link
Member

If nobody objects, then I can start looking into switching the library to JSDoc types where possible, with .d.ts elsewhere (eg. for the auto-generated space accessor types)

I meant to get this done a while ago, but I've been a lot busier than I expected over the past few weeks. I'm not going to be available to work on this until at least May 22. If anybody else would like to implement this, feel free to do so and let me know. Otherwise, I can work on it then 😄

@LeaVerou LeaVerou added this to the v0.6.0 milestone May 24, 2024
@MysteryBlokHed MysteryBlokHed linked a pull request May 26, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Topic: Documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants