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

Distribute TypeScript types with koa package #1607

Open
justinfagnani opened this issue Nov 5, 2021 · 8 comments
Open

Distribute TypeScript types with koa package #1607

justinfagnani opened this issue Nov 5, 2021 · 8 comments
Assignees

Comments

@justinfagnani
Copy link

It'd be really convenient if the Koa types were distributed with the koa package rather than requiring a separate install of @types/koa.

I see that requests for a TypeScript rewrite have been closed, but could the types at least be pulled in? It might help keep them in sync as well.

@jimmywarting
Copy link

sometimes i don't get it, vscode is able to follow js and understand jsdoc without having separate type definition files. I most often see this @types as unnecessary

@miwnwski
Copy link
Member

miwnwski commented Jul 1, 2022

I'll leave this open for now but there's little engagement from maintainers to add/update TS support in any form to this repo.

@justinfagnani
Copy link
Author

That's unfortunate.

I know npm download numbers aren't perfectly representative, but I'd bet that significant fraction of your users are using Koa via TypeScript and would benefit from typings being in sync.

Screen Shot 2022-07-01 at 8 14 00 AM

@miwnwski
Copy link
Member

miwnwski commented Jul 1, 2022

Sure, maybe. I get it. I just have no personal stake in getting TS in so I will not push for it. If anything adding TS typings might just push me to leave entirely (not that anyone would care :), I'm just saying, it's not an investment I care to take on at least).

Edit: Ooops, sorry, closed by mistake.

Also, I just want to clarify by "leaving". I ment as a member of the maintainer group. I'm not active enough to take decisions like these anyway, so I just peak when I find the time. I could do some minor stuff when necessary but if I also had to consider TS (which I'm personally not a fan of) I would just accept that Koa isn't for me to care about anymore :). Maybe the next generation of Koa users would consider it, but again, I'm not even comfortable inviting new members at this point due to my inactivity here!

@miwnwski miwnwski closed this as completed Jul 1, 2022
@miwnwski miwnwski reopened this Jul 1, 2022
@jaydenseric
Copy link

The best way to add type safety to Koa would be to use TypeScript JSDoc comments.

Add a typescript dev dependency:

https://github.com/jaydenseric/graphql-api-koa/blob/b8aac9a2927ec9aeb0954b93e170e4604aa676f5/package.json#L59

"typescript": "^4.7.4"

Because koa types probably reference Node.js types, the @types/node package should be a dependency with a * version:

https://github.com/jaydenseric/graphql-upload/blob/aa15ee0eb2b3a4e2421d098393bbbf9252f1a8c7/package.json#L65

"@types/node": "*",

If Node.js types are only used in non-published modules (i.e. tests) then it could be a dev dependency instead with the latest version:

https://github.com/jaydenseric/graphql-api-koa/blob/b8aac9a2927ec9aeb0954b93e170e4604aa676f5/package.json#L49

"@types/node": "^18.0.0",

Any other @types/ required for dependencies that don't ship their own types should be added as either dev or prod dependencies, depending if they are used in published modules.

In edge cases you could add types as optional peer dependencies if your package ships modules for multiple different frameworks where a user is expected to only use one in their project, for example graphql-upload exports middleware for both Koa and Express, and a user is not expected to have the types for both present in their project:

https://github.com/jaydenseric/graphql-upload/blob/aa15ee0eb2b3a4e2421d098393bbbf9252f1a8c7/package.json#L55-L62

Add a jsconfig.json file like this:

https://github.com/jaydenseric/graphql-api-koa/blob/b8aac9a2927ec9aeb0954b93e170e4604aa676f5/jsconfig.json#L1-L11

{
  "compilerOptions": {
    "maxNodeModuleJsDepth": 10,
    "module": "nodenext",
    "noEmit": true,
    "strict": true
  },
  "typeAcquisition": {
    "enable": false
  }
}

Then add a type check package script like this:

https://github.com/jaydenseric/graphql-api-koa/blob/b8aac9a2927ec9aeb0954b93e170e4604aa676f5/package.json#L64

"types": "tsc -p jsconfig.json",

That doesn't emit anything, it just checks the types of the project modules for CI.

Add this at the top of any modules you want type checked (usually all of them):

https://github.com/jaydenseric/graphql-api-koa/blob/b8aac9a2927ec9aeb0954b93e170e4604aa676f5/execute.mjs#L1

// @ts-check

Then you can use TypeScript JSDoc comments for type safety, like this:

https://github.com/jaydenseric/graphql-api-koa/blob/b8aac9a2927ec9aeb0954b93e170e4604aa676f5/execute.mjs#L39-L98

I truly believe this is as simple as it gets for having type safety as the types are inherently part of the modules that are shipped, and there is no build step. This is particularly great when publishing universal modules that work in both Node.js and Deno projects with TypeScript, as Deno with HTTP imports doesn't have a concept of node_modules or @types/ packages. I've been rolling out type safety via TypeScript JSDoc comments to all of the Node.js and Deno packages I publish. This has only been viable in the last year or so; since TypeScript added support for modern Node.js module resolution for .mjs, package exports field, etc. via the TypeScript config compilerOptions.module mode nodenext/node16.

Koa already is using relatively detailed JSDoc comments, so setting all this up would not be too difficult:

koa/lib/application.js

Lines 34 to 44 in 00ce71f

/**
*
* @param {object} [options] Application options
* @param {string} [options.env='development'] Environment
* @param {string[]} [options.keys] Signed cookie keys
* @param {boolean} [options.proxy] Trust proxy headers
* @param {number} [options.subdomainOffset] Subdomain offset
* @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
* @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
*
*/

@mihailik
Copy link
Contributor

mihailik commented Dec 7, 2022

Minded to add a PR for some very basic improvements to existing JSDoc 👍

@jimmywarting
Copy link

Add // @ts-check at the top of any modules you want type checked (usually all of them):

Usually what i do is enabling widespread checkjs, this can be done in vscode settings.json or in a .vscode/settings.json for individual workspace or via tsconfig.json or jsconfig.json. Then you don't have to add that to every file

{
  // The 3 most important one:
  "js/ts.implicitProjectConfig.checkJs": true,
  // Enable suggestion to complete JSDoc comments.
  "javascript.suggest.completeJSDocs": true,
  // Preferred path ending with extension (good for both esm & cjs).
  "javascript.preferences.importModuleSpecifierEnding": "js",
  
  // Other suggestions useful stuff:
  // Complete functions with their parameter signature.
  "javascript.suggest.completeFunctionCalls": true,
  // Enable auto import suggestions.
  "javascript.suggest.autoImports": true
}

@jaydenseric
Copy link

@jimmywarting editor or TypeScript config doesn't get published or used when the package is installed by users. You don't just want type safety for the source code of the package you are authoring, but also for your users consuming the published package.

@kevinpeno kevinpeno self-assigned this Oct 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants