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

Generate type declaration files #118

Merged
merged 14 commits into from
Sep 18, 2023
Merged

Generate type declaration files #118

merged 14 commits into from
Sep 18, 2023

Conversation

claytercek
Copy link
Member

@claytercek claytercek commented Aug 30, 2023

  • Added tsconfigs to generate .d.ts files
  • Fixed all type errors
  • Added a 'build' step to main workflow as an additional check to verify types are building correctly
  • Added a 'build' step to the release workflow, so that types are generated before being uploaded to npm

resolves #117

@claytercek
Copy link
Member Author

claytercek commented Aug 30, 2023

Leaving this PR as a draft for now, as there are a couple of open questions. Everything builds successfully right now, but there are a lot of properties typed as */object/any, which is generally seen as a TS antipattern. Once we answer some of these questions, we can go through and try to narrow the types as much as possible.

Now that we have type checking, I wonder if it would be worth rethinking some of the patterns in the repo to take advantage of it, specifically the way we're handling options.

I think it would be cleaner, and a bit less redundant to define options as types rather than classes, ie this:

/**
 * @typedef SomeOptions
 * @param {boolean} option1 - option 1 description
 * @param {boolean} option2 - option 2 description
 */

instead of our current pattern, which looks something like this:

class SomeOptions {
  /**
   * @type {boolean} 
   */
  option1;

  /**
   * @type {boolean} 
   */
  option2;

  /**
   * 
   * @param {object} options
   * @param {boolean} options.option1
   * @param {boolean} options.option2
   */
  constructor(options) {
    this.option1 = options.option1;
    this.option2 = options.option2;
  }
};

Not sure if this is something that should be held off for a different PR.

@benjaminbojko any thoughts?

@claytercek
Copy link
Member Author

claytercek commented Aug 30, 2023

Update: fixed. See comment below.


One more hiccup I ran into while working on the plugin API (#114):

Right now, the only types that are accessible are those exported in the index.js of each package. If we want to share types (or jsdoc @typedefs) between packages, we don't currently have a way of doing that, as there's no way to export just a type from a js file.

For instance, I'm defining Hook and Plugin types in utils that I would like to use/extend in content, but there's no way to access those types.

Some easy but inelegant solutions off the top of my head:

  1. generate the .d.ts files alongside the .js instead of in a dist directory. TS is smart enough to look for declaration files alongside the js, so users could reference the file that includes the type directly (like @type {import("@bluecadet/launchpad-utils/lib/plugins").Hook} in JSDOC syntax). Not my favorite solution, as it co-mingles the source code and generated code.

  2. disable the emitDeclarationOnly tsconfig option, so that js is written alongside the .d.ts files in the dist directory. Users could then import the js with types from the dist directory, but this is just unnecessary duplication.

  3. go all in on esmodules, and add an exports property to the package.json with explicit paths to any files that would need to share types:

    {
      "name": "@bluecadet/launchpad-utils",
      "version": "1.4.0",
      "description": "Common utilities used by multiple launchpad modules",
      "type": "module",
    -  "main": "index.js",
    -  "types": "dist/index.d.ts",
    +  "exports": {
    +    ".": {
    +      "default": "./index.js",
    +      "types": "./dist/index.d.ts"
    +    },
    +    "./plugins": {
    +      "default": "./lib/plugins.js",
    +      "types": "./dist/lib/plugins.d.ts"
    +    }
    +  }
    }

Gonna research some other options to see if there's a 'nicer' way to accomplish this.

@claytercek
Copy link
Member Author

Found a workaround from this blog for the shared types issue above. Types imported directly from lib files works now.

@claytercek
Copy link
Member Author

Per our conversation, breaking the updated options typings and removal of vague any types into a separate issue #119

@claytercek claytercek marked this pull request as ready for review August 31, 2023 19:10
@benjaminbojko
Copy link
Collaborator

Will check this out locally and review asap.

@claytercek
Copy link
Member Author

Looks like the docs generation is pretty broken with these updates. Seems like the official JSDoc lib doesn't support a lot of typescript syntax (namely using import(...), type expressions, and question marks for optional properties).

Gonna research to see if there are plugins for JSDoc that could fix this, and check to see if TypeDoc could be a drop-in replacement.

@benjaminbojko
Copy link
Collaborator

Thanks! FWIW I think the docs could use a refresh, especially pending our discussion around #116 . So if you find this to be a major hurdle, I'd err on the side of merging this in and creating a new issue to resolve docs generation.

@claytercek
Copy link
Member Author

Yeah it's looking like there's not really a quick fix for this. We can merge into dev but hold on releasing until we have the updated docs?

@claytercek claytercek mentioned this pull request Sep 18, 2023
@benjaminbojko
Copy link
Collaborator

Yes, sounds good! Could you merge and create a new issue for revisiting jsdoc generation?

@claytercek claytercek merged commit 3f0f586 into develop Sep 18, 2023
@claytercek claytercek deleted the feat/strict-typing branch September 18, 2023 23:38
@github-actions github-actions bot mentioned this pull request Sep 18, 2023
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.

2 participants