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

Add basic jsdoc tag types #610

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

sandersn
Copy link
Member

Just a draft right now. @type, @param and @return attach their types to their host's type annotations. These are not marked as synthetic yet, pending #521 to make the decision how to do so.

@typedef emits a new JS type alias statement just before the jsdoc's host. In contrast to the other tags, the JS type alias has a separate kind and needs to be handled alongside normal type aliases. This isn't very valuable for type aliases, but will be more valuable for, say, CommonJS imports and exports, which have semantics that are different from TS' CommonJS import/export statements.

TODO (among many other things):

  • Translate the bottom-up host-to-tag search completely to top-down search. It's very basic right now.
  • Look at baseline diffs and squash bugs.
  • Get rid of the synthetic JS type wrapper.
  • Update to mark new nodes as synthetic once Synthetic export for nested namespace, redux #521 is merged.

sandersn added 12 commits March 6, 2025 13:49
I chose to create a wrapper type node for synthetic JS types rather than
cloning the type node. This is how many other tags are going to work,
like `@typedef` and `@overload`, so I think it makes sense.

However, running tests points out that `@type` assertions, `@satisfies`,
and the modifier-like tags like `@private` and `@readonly` will need to
emit non-wrapped synthetic nodes, much like in microsoft#412.

Much more work to be done here on replicating the host<->tag matching
rules from Strada.
For example, recursive uses aren't done yet. Test diffs look generally
right but are hard to evaluate without typedef and template tags,
specifically.
Written mostly by AI, without reference to the original source. So it's
going to need some cleanup.
@@ -3032,6 +3046,7 @@ type ClassLikeBase struct {
DeclarationBase
ExportableBase
ModifiersBase
LocalsContainerBase
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike type, @typedef is allowed as a local inside classes.

I haven't checked to see how common this is so I added support for now as a way of fixing a nil panic. But I will remove it if it's not common.

@@ -3268,6 +3283,55 @@ func IsTypeAliasDeclaration(node *Node) bool {
return node.Kind == KindTypeAliasDeclaration
}

func IsEitherTypeAliasDeclaration(node *Node) bool {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to improve this name, maybe by asking Copilot for a name that sounds a little like a Pokemon.

- Transform `@typedef`+`@property` in a type object literal.
- type check JSDoc types
- add `@param` optionality when bracketed.
- refactor `@template` parsing to share constraints in multi-parameter
  tags
- type `@template` tags
- type assertions on parenthesised expressions
- miscellaneous fixes
- I looked at the diffs for compiler/ tests and skimmed the conformance/
  ones. There are still some failures I want to fix.
nameresolver still needs to check for JS nodes because it will often
start a walk upward looking at the *original* type nodes deeply nested
in JSDoc. When it hits the JSDocTypeExpression, it should move over to
the type expression's hosted position in the tree, such as a real
parameter.

The JS code is much less intrusive than before though.
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.

1 participant