govuk-frontend
govuk-frontend copied to clipboard
Export type declarations for component source code
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:
here's an example @cloudratha did for the hackney fork of this lib. doing it here would probably look similar:
https://github.com/LBHackney-IT/lbh-frontend/pull/177
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.jsonis a descendant of tsconfig.json, which is a configuration file for TypeScript.jsconfig.jsonistsconfig.jsonwith "allowJs" attribute set totrue.
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?
- Manually write type declarations
- Keeping our JavaScript source, but output type declarations via
tsc+ JSDoc - 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 😊
For anyone else searching I'll put these notes here
Thanks again
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.
We're going to put this one back in the backlog for a bit, the time to prioritise our work.
Just a note from TypeScript’s Publishing guide as they suggest types are published by either:
- bundling with your npm package
- publishing to the @types organization on npm.
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
@typesorganization 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 https://github.com/alphagov/govuk-frontend/commit/a4c0877707f589ddb540ea62bfcd226287ce2d1d on branch component-data-jsdoc
https://github.com/alphagov/govuk-frontend/blob/39c0a23edd3c47c27954c601168d1ede342c3920/shared/lib/components.js#L154-L156
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