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

Ensure JSDoc blocks are complete #3102

Merged
merged 2 commits into from
Dec 16, 2022
Merged

Ensure JSDoc blocks are complete #3102

merged 2 commits into from
Dec 16, 2022

Conversation

colinrotherham
Copy link
Contributor

@colinrotherham colinrotherham commented Dec 15, 2022

This PR completes a review of all JSDoc comments for completeness

All blocks are now documented with descriptions, parameters and optional return (or throws) types

/**
 * Example method
 *
 * @param {Element} $header - Section header
 * @param {number} index - Section index
 * @returns {Accordion} Accordion component
 */
Accordion.prototype.example = function ($header, index) {
  var $example1 = $header.querySelector('.' + this.example1Class)
  var $example2 = $header.querySelector('.' + this.example2Class)

  // Code goes here
  return this
}

Which continues work we started for v4.4.0:

To assist with code reviews I've split these changes into:

  1. Ensure JSDoc blocks are complete #3102
  2. Configure ESLint to require JSDoc @params etc #3103
  3. Various JSDoc + type checking fixes #2987
  4. Enable type declaration guards #3123
  5. Add (optional) type declaration checks in app, src #3104

Resolves #2513

All blocks are documented with a description, params, optional return (or throws) types and “this” where instantiated or bound
Copy link
Member

@romaricpascal romaricpascal left a comment

Choose a reason for hiding this comment

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

Looks pretty neat! Thanks for going over those 🙌🏻 Just spotted a little type issue with the config I think 😄

* @param {object} configObject - Deeply nested object
* @returns {object} Flattened object with dot-separated keys
* @param {Object<string, any>} configObject - Deeply nested object
* @returns {Object<string, string>} Flattened object with dot-separated keys
Copy link
Member

Choose a reason for hiding this comment

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

issue I don't think that's the right type here. The configuration values may be numbers (in the character count) or booleans (in the button), so we also return Object<string, any>. That returned any won't be an object as things are flattened, but I don't think that's something we need to specify.

Suggested change
* @returns {Object<string, string>} Flattened object with dot-separated keys
* @returns {Object<string, any>} Flattened object with dot-separated keys

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great spot, and it's found another potentially crashing bug too

We're trusting that translation "strings" in I18n() are always strings
https://github.com/alphagov/govuk-frontend/blob/main/src/govuk/i18n.mjs#L46

I might try and use unknown (checks needed) instead of any (doesn't matter)

Copy link
Contributor Author

@colinrotherham colinrotherham Dec 15, 2022

Choose a reason for hiding this comment

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

Yep all works with Object<string, unknown> 👍

I've removed the TranslationsFlattened type as it was fibbing 😬

/**
 * Translated messages (flattened)
 *
 * @private
 * @typedef {Object<string, string> | {}} TranslationsFlattened
 */

You'll see some extra commits in the other PR now to check for string/number/boolean values:

* @param {string} namespace - The namespace to filter keys with.
* @returns {object} Flattened object with dot-separated key namespace removed
* @returns {Object<string, string>} Flattened object with dot-separated key namespace removed
Copy link
Member

Choose a reason for hiding this comment

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

issue Same issue as before with the values of the object

Suggested change
* @returns {Object<string, string>} Flattened object with dot-separated key namespace removed
* @returns {Object<string, any>} Flattened object with dot-separated key namespace removed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed as above 👍

@@ -36,6 +36,7 @@ var ACCORDION_TRANSLATIONS = {
* @class
* @param {HTMLElement} $module - HTML element to use for accordion
* @param {AccordionConfig} [config] - Accordion config
* @this {Accordion}
Copy link
Member

Choose a reason for hiding this comment

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

question From what I gathered, this only changes the label of "this" in the first line when hovering this inside the function. Does it bring some technical info (eg. to TypeScript when type checking) or is it just informative when hovering/in JSDoc?

Screenshot 2022-12-15 at 09 51 30

@class seems to already do the important lifting of typing this to an accordion and we have the header of the documentation to remind us of that if we drop it.

Screenshot 2022-12-15 at 09 51 39

Completions also work OK without it:

Screenshot 2022-12-15 at 09 51 48

Copy link
Contributor Author

@colinrotherham colinrotherham Dec 15, 2022

Choose a reason for hiding this comment

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

Yeah I think it came from a brief time I was trying to run in strict mode

Accordion() // this === window
new Accordion() // this === instanceof Accordion

Where inside our constructor function we'd technically need to add:

function Accordion ($module, config) {
  if (!(this instanceof Accordion)) {
    return new Accordion($module, config);
  }
}

☝️ Old trick to detect the missing new and returns an instance of itself

Shall I get rid? Won't need it once we switch to classes anyway

Copy link
Member

Choose a reason for hiding this comment

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

I'd be keen to drop the @this then, yeah, to not carry its limited value 😄

(not sure if you were proposing to introduce the check for use as a function rather than a constructor, but given that'd expand our API to allow function right before we'd contract it back by switching to classes, I don't feel it's necessary either).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nah too much overhead. Compiler was right but we can live with it for now

I've removed @this from JSDoc and updated the coding standards to match

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3102 December 15, 2022 11:21 Inactive
All blocks are documented with a description, params and optional return (or throws) types
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-3102 December 15, 2022 17:10 Inactive
Copy link
Member

@romaricpascal romaricpascal left a comment

Choose a reason for hiding this comment

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

Thanks for making the updates 😄 Looks good to go 🚀

* Translated messages (flattened)
*
* @private
* @typedef {Object<string, string> | {}} TranslationsFlattened
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed as config objects from extractConfigByNamespace() have mixed values

(Not just strings)

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

Successfully merging this pull request may close these issues.

Some component JavaScript is complex and difficult to follow
3 participants