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

Export type declarations for component source code #2835

Open
jhackett1 opened this issue Sep 11, 2022 · 6 comments
Open

Export type declarations for component source code #2835

jhackett1 opened this issue Sep 11, 2022 · 6 comments
Labels
feature request User requests a new feature javascript tooling

Comments

@jhackett1
Copy link

jhackett1 commented Sep 11, 2022

it would be great if this library declared its types, to make it easier to understand what i can import from it and how it can be used.

at the moment, when i import it in a typescript project, i get an error:

Could not find a declaration file for module 'govuk-frontend'. '/Users/jayehackett/Downloads/wp-fiddle/node_modules/govuk-frontend/govuk/all.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/govuk-frontend` if it exists or add a new declaration (.d.ts) file containing `declare module 'govuk-frontend';`

i could perhaps make a pull request for this if it's wanted?

Context

Alternatives

i could define some a declaration file in my own project, but that would only solve the problem for me!

Additional information (if applicable)

for a library like this, including types is a useful form of self-documentation. it's nice to be able to import a library and see intellisense suggestions for what i can do with it without having to refer to a documentation website.

for example, this works, but my editor doesn't "know" that it works:

Screenshot 2022-09-11 at 18 26 45

@jhackett1 jhackett1 added awaiting triage Needs triaging by team feature request User requests a new feature labels Sep 11, 2022
@jhackett1
Copy link
Author

here's an example @cloudratha did for the hackney fork of this lib. doing it here would probably look similar:

LBHackney-IT/lbh-frontend#177

@colinrotherham
Copy link
Contributor

Thanks @jhackett1 for raising this issue

I know things have been quiet (or silent) from our end on this but it's certainly been talked about.

For now, you're likely seeing problems because "strict": true is set in your TypeScript compilerOptions. For any regular JavaScript code without type declarations, ours included, you'll see the same.

Microsoft have some more tips here for regular JavaScript:
https://code.visualstudio.com/docs/languages/jsconfig

Tip: jsconfig.json is a descendant of tsconfig.json, which is a configuration file for TypeScript. jsconfig.json is tsconfig.json with "allowJs" attribute set to true.

Generated type declarations in future

That said, we appreciate type declarations are a brilliant way of bringing documentation straight to the code

What could we do in the future?

  1. Manually write type declarations
  2. Keeping our JavaScript source, but output type declarations via tsc + JSDoc
  3. Converting to TypeScript source, but compiling to JavaScript with type declarations via tsc

Mainly with 2) in mind, we've started taking a look at improving our JSDoc comments as we know the TypeScript compiler (and your editor or IDE's language server) will automatically pick these up

Automatic type discovery now

What do we have already?

If you're using an editor or IDE (Visual Studio Code, Sublime Text, WebStorm) with plugins that wrap the TypeScript standalone server (aka tsserver) you'll already see type information from node_modules appearing in your code.

I had a quick try and our JSDoc comments (where we use them) are appearing already 😊

JSDoc comment for Checkboxes prototype syncAllConditionalReveals shows available params

For anyone else searching I'll put these notes here

Thanks again

@beejjacobs
Copy link

To add to this, our workflows over at the Planning Inspectorate would benefit from exported types. For now we are defining our own types to go along with the library.

We use plain JavaScript instead of TypeScript, but TS is key to understanding the types a library needs, and is what vscode uses to check code too.

We often have a need to know the type of a nunjucks macro function - i.e. what data can we pass to a particular macro; being able to check the types for that (and have it autocomplete etc...) would be useful.

@romaricpascal
Copy link
Member

We're going to put this one back in the backlog for a bit, the time to prioritise our work.

@colinrotherham
Copy link
Contributor

colinrotherham commented Jan 18, 2024

Just a note from TypeScript’s Publishing guide as they suggest types are published by either:

I’ve picked the easiest option 1) to generate types alongside source (#4094, #4154) so this caveat applies:

If your types are generated by your source code, publish the types with your source code. Both TypeScript and JavaScript projects can generate types via declaration.

Which would then steer us away from DefinitelyTyped:

Otherwise, we recommend submitting the types to DefinitelyTyped, which will publish them to the @types organization on npm.

But to avoid accidentally-breaking type changes, perhaps this still leaves an optional @govuk-frontend/types package as a valid option, without DefinitelyTyped?

Type checking Nunjucks

In future, we could consider a custom filter or function (opt-in only) that enables Nunjucks type checking:

We often have a need to know the type of a nunjucks macro function - i.e. what data can we pass to a particular macro; being able to check the types for that (and have it autocomplete etc...) would be useful.

The filter could log warnings or throw errors at Nunjucks compile time when options are deprecated or invalid:

govukAccordion({
  rememberExpanded: false
} | validate('AccordionConfig'))

Autocomplete

Unfortunately, code autocomplete via types would only be available in JavaScript templating languages.

We'd need to move our YAML documentation into JSDoc to support this and I've demonstrated JavaScript versions of govukAccordion(), govukBackLink() etc in a4c0877 on branch component-data-jsdoc

function render(componentName, options) {
const macroName = componentNameToMacroName(componentName)
const macroPath = `govuk/components/${componentName}/macro.njk`

JavaScript versions of govukAccordion(), govukBackLink() etc are wrappers for our render('accordion', options) Nunjucks lib functions used by our tests, but ensuring that options either becomes a JSDoc @template matched on the component name or separate JSDoc block

If support was needed, these wrappers could be used in JSX and other JavaScript templating languages

@colinrotherham colinrotherham removed their assignment Mar 10, 2024
@colinrotherham
Copy link
Contributor

To share an update on this, I've contributed a community @types/govuk-frontend package via:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request User requests a new feature javascript tooling
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants