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

Show members of a type alias #2260

Closed
cefn opened this issue Apr 23, 2023 · 8 comments
Closed

Show members of a type alias #2260

cefn opened this issue Apr 23, 2023 · 8 comments
Labels
enhancement Improved functionality

Comments

@cefn
Copy link

cefn commented Apr 23, 2023

Search Terms

Expand type members/properties
Inherited type members/properties

Feature request

Can we add a configuration or comment directive that would cause typedoc to show the members of a type alias? Typescript is able to detect they are there, but currently Typedoc doesn't show them.

Problem

I composed Store - the core type of my library through distinct interfaces and types which can be reasoned about, documented and tested independently. However, the result of using interface inheritance and type aliases to compose Store is that Typedoc gives it no visible members at all in its documentation, making the API documentation from typedoc of very limited value for this case.

You can see the generated documentation for Store at https://cefn.com/lauf/api/types/_lauf_store.Store.html . The documentation omits the crucial watch, read and write methods from WatchableState.

Store Hierarchy

  • Watchable<T> defines a subscription method (watch()) for tracking a T
  • WatchableState<T> extends Watchable<T> with read() and write() methods to set and get a T
  • Immutable<T> is a recursive-applied Readonly<T>

A Store<T> is composed as the type alias WatchableState<Immutable<T>>

Existing Features

The Typescript compiler can resolve what members Store has, which is demonstrated during auto-completion...

image

I don't think following the typedoc links to the separate interfaces Watchable, WatchableState, Immutable helps the average person work out what the methods of Store<T> are, once they have lost context and are looking at a different type.

I can't identify any configuration that causes types to have the detail of their members exhaustively listed. There doesn't seem to be anything that can be added to a type's header comments to trigger this either.

I have tried to exhaustively understand all the options available but none seems to cover this case.

I tried to establish if typedoc-plugin-expand-object-like-types would show the members. However that plugin is pinned to an older typedoc version, and I have just finished refactoring all my documentation to align with the requirements of typedoc 0.24.x. Rolling back to 0.23.x raises a lot of warnings of unresolved and broken links now. I force-installed the plugin against 0.24.x, but this didn't have the desired effect of adding visible members to the Store definition..

Thanks for considering my feature request.

@cefn cefn added the enhancement Improved functionality label Apr 23, 2023
@cefn
Copy link
Author

cefn commented Apr 23, 2023

For now, I've gone back to typedoc 0.23.x as it's a little better for my case. I found that typedoc-plugin-expand-object-like-types DOES indeed cause members to be expanded.

To fix the errors with the less capable resolver of 0.23.x I manually added all the @lauf/store! module path prefixes to symbols which couldn't be resolved.

I also have the following benefits from 0.23.x so I will pin my project for now, until I can get plugins to fix the problems of 0.24.x...

  • a list of types now appears when you click on a module (this was apparently broken/retired in 0.24.x) - clicking on e.g. @lauf/store would show the documentation, but none of its classes or types in the module were visibly expanded without hunting down the little triangle beside the module name
  • types in definitions were hidden by default, so in 0.24.x I had to re-enable showing types using "hideParameterTypesInTitle": false, so that e.g. Watcher<T> was shown as (item:T) => unknown and not (item) => unknown which otherwise defeats the point of showing its definition.

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Apr 23, 2023

This sounds like the @interface tag to me

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Apr 24, 2023

Thanks for the very useful project for test data! I experimentally upgraded it to use TypeDoc 0.24 again, and changed the configuration up to use TypeDoc's packages mode + TypeScript's project references (definitely not necessary for your smallish project, but it's intended for monorepos, and enables getting rid of the per-module comments to set the name and include the readme)

This resulted in finding a couple bugs, released in v0.24.6. TS link resolution wasn't used within block tags, and the modules not expanding when active was confirmed and fixed. Store.watch is now rendered as:

image

@cefn
Copy link
Author

cefn commented Apr 24, 2023

Thanks, @Gerrit0 I feel privileged to have your time and attention supporting me!

I'd certainly be more comfortable with mainline typedoc rather than being pinned and relying on plugins. It's reassuring to learn that the behaviour I was expecting is the intended default!

I've completed this iteration of the documentation in anticipation of releasing the final version in the @lauf namespace, (switching to @watchable from now on). Just trying to get both API docs, github docs, stackblitz docs and npm package docs to play nice together ( https://www.npmjs.com/package/@lauf/store/v/2.0.0-beta.3 ). I am really looking forward to circling back and benefiting from the latest typedoc, though!

You've also taught me some important config changes which I should examine - new bundler resolution, tsc -b and more. So far I've been avoiding these as there is no actual output, (dist bundle is handled by vite/esbuild) and build is incompatible with noEmit I think, so tsc is running purely as a QA check and to give feedback from the compiler. Anything to accelerate builds is good though, so I should revisit.

When I revisit documentation I'll be sure to share any bugs that appear if this is a useful reference repo for you, and I'll try to align with the build changes you've proposed at that time.

@cefn
Copy link
Author

cefn commented Apr 30, 2023

I spent a few hours attempting to align the project with your suggestions with this PR, and then was stalled for several more hours with the problem that I can't stop vite.config.ts from being built to a vite.config.js and a vite.config.d.ts which breaks linting and creates confusing and pointless files built in the source tree. Everything else works well.

This has followed from some change to the cascading structure of tsconfig imports. I believe I've followed all the steps you shared, but I may have missed one.

This is not your problem of course, but I'm sharing as in practice it is the cascade of fragile config relationships and incompatibilities that consumes all the time when trying to adopt a tool like typedoc and it's good for you to be aware, maybe? Not sure if any choices within typedoc could make a difference.

To ensure that all the targets of npm run qa would succeed, not just the doc target, I needed to bring some of the typedoc-oriented tsconfig down to ./packages level (not the top level tsconfig, which defines module aliases and therefore is shared by ./apps in the monorepo - and which have a tsconfig coupled to vite). This has been an attempt to prevent a cascade of typescript emit happening in the wrong places.

Problem

If I try to run the qa task the unnecessary creation of files like vite.config.d.ts generated by the build step breaks the pipeline when they fail linting.

Running ```git clean -fdx && npm install && npm run qa` fails at the linting phase. Checking status shows extra files were created which don't satisfy the linter (but should not have been created at all).

git status
Your branch is up to date with 'origin/latest-typedoc'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        apps/counter-preact-ts/vite.config.d.ts
        apps/counter-preact-ts/vite.config.js
        apps/counter-react-ts-edit-context/vite.config.d.ts
        apps/counter-react-ts-edit-context/vite.config.js
        apps/counter-react-ts-edit/vite.config.d.ts
        apps/counter-react-ts-edit/vite.config.js
        apps/counter-react-ts/vite.config.d.ts
        apps/counter-react-ts/vite.config.js

I am between a rock and a hard place here given every layer of tooling implicitly requires a different tsconfig structure and that --build requires noEmit:false at certain places. Additionally the error feedback is byzantine whenever a change is made to the transpilation and bundling layers of the project.

Focusing in on one reference app counter-react-ts, trying to prevent it creating these unnecessary vite config artefacts (which were never generated before) I tried some different changes followed by running git clean -fdx . && npm install && npm run build from within that app module folder...

1) Remove this line

Remove below line from tsconfig.node.json causes a jsx error out of the blue

  "include": ["vite.config.ts"]

1) Error

🏃 [build] Running command "tsc --build && vite build"
src/main.tsx(3,21): error TS6142: Module './ui' was resolved to '/home/cefn/Documents/github/watchable/apps/counter-react-ts/src/ui.tsx', but '--jsx' is not set.
src/main.tsx(6,3): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.

2) Add line

As an alternative I could try adding a noEmit to the tsconfig.node.json

    "noEmit": true

2) Error

This results in the following failure instead that tells me I may not disable emit...

🏃 [build] Running command "tsc --build && vite build"
tsconfig.json(22,18): error TS6310: Referenced project '/home/cefn/Documents/github/watchable/apps/counter-react-ts/tsconfig.node.json' may not disable emit.
❌ [build] Failed with exit status 2

Summary

Magic-config dead ends like this which consume hours are fairly typical of my experience working within the ecosystem. Not sure what any maintainers can do about it, honestly, but the result is people not progressing with the fundamentals (features, actual code) while they face these blockers each of which require interpreting and understanding every layer of the transpilation and bundling process which is by no means a black box.

For this particular issue I've no idea what has changed to cause vite.config.ts to be considered as a target for emitting actual code, and why I can't remove it from the scope of this process, even though it was never transpiled before.

@cefn
Copy link
Author

cefn commented Apr 30, 2023

Final restructure of app build (to isolate them fully from the top level configs) in cefn/watchable@ef96cf1 seems to have suppressed the creation of vite.config build artefacts. Now I need to see whether anything else breaks if I follow that through for all Typescript apps.

Update: this was apparently not true, maybe due to some kind of cached build artefacts.

@cefn
Copy link
Author

cefn commented Apr 30, 2023

Actually after updating every app in line with this change, the artefact now seems to be coming from somewhere else, and is still coming.

Running the following against https://github.com/cefn/watchable/tree/53db54b4cc15159844d9df26f2ee8394b9587e55

git clean -fdx ; npm install ; npm run build && npm run lint --workspaces

...I still have a failing lint task in the pipeline and lots of unnecessary vite.config files emitted...

watchable git:(latest-typedoc) ✗ git status                                                               
On branch latest-typedoc
Your branch is up to date with 'origin/latest-typedoc'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        apps/counter-dom-ts/vite.config.d.ts
        apps/counter-dom-ts/vite.config.js
        apps/counter-preact-ts/vite.config.d.ts
        apps/counter-preact-ts/vite.config.js
        apps/counter-react-ts-edit-context/vite.config.d.ts
        apps/counter-react-ts-edit-context/vite.config.js
        apps/counter-react-ts-edit/vite.config.d.ts
        apps/counter-react-ts-edit/vite.config.js
        apps/counter-react-ts/vite.config.d.ts
        apps/counter-react-ts/vite.config.js

Weirdly if I run the above failing task then change into one of the app directories and run the same operation from there (the git clean removes any build cache)

git clean -fdx ; npm install ; npm run build && npm run lint

@cefn
Copy link
Author

cefn commented Apr 30, 2023

Finally, removing references to vite's tsconfig.node.json eliminated the problem. I think this is there to accelerate vite builds maybe? It doesn't seem to have any effect removing the line, but with it, we have vite.config.ts being built to artefacts all the time.

The line (which references the tsconfig.node.json path) has been there since the vite apps were built, so I don't know why that interacts with the changes which were made to satisfy typedoc all of a sudden.

This change solves the problem cefn/watchable@d255444

Now a failure from playwright upstream has broken the build instead, meaning it doesn't build on github any more so looking forward to another day dealing with that problem before I write any code :)

@cefn cefn closed this as completed Apr 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improved functionality
Projects
None yet
Development

No branches or pull requests

2 participants