Hacker News new | ask | show | jobs
by culi 193 days ago
> Today in 2025, TS offers so much more than the (TS)JSDoc implementation. Generics, Enums, Utility types, Type Testing in Vitest, typeguards, plus other stuff.

This was my main impetus for writing this article. Modern JSDoc uses the TypeScript language service. You can use generics, utility types, typeguards (including the `is` keyword), regex parsing, etc all with just JSDoc.

I used these features extensively (especially generics) in a personal project and managed to do it all in JSDoc.

3 comments

JSDoc is missing a lot of basic capabilities. For example a TypeDef is automatically exported which can cause collisions and forces you to repeat or inline types.

Types for classes are poor and often you'll find yourself creating a `.d.ts` file or `.ts` file to export non trivial types - however the target file doesn't know how to consume them.

typedefs are indeed automatically exported but that doesn't mean collisions can happen. You would still have to explicitly import a type

Regardless, I hardly consider that a "missing basic capability"

I don't know what you mean about types for classes being "poor". Types for classes work exactly the same way

You cannot replicate `import type { x } from './foo'` without also re-exporting that import - which causes collisions.

The alternative is to do an inline `const foo = /** @type {import('./foo').x} */ ({})` however this gets messy, repetitive and it's difficult to use algebraic types (e.g. `Event & { detail: string }`)

Would `import type { x as y } from `./foo.x` not work?
JSDoc does not understand typescript syntax though? The typescript language server just kinda plows through/over JSDoc sure, but try getting JSDoc to parse some of the TS-ified things that JSDoc has alternatives for.

https://github.com/jsdoc/jsdoc/issues/1917

https://github.com/jsdoc/jsdoc/issues/1917#issuecomment-1250...

tuples, `&` operator, and even generics all work perfectly well inside a `@type` declaration. For example:

```js

  /**
   * @type {{
   *   slug: `${string}_${number}`;
   *   id: number;
   * } & { status?: [code: number, text: string]; }}
   */
  const example = { slug: 'abc_34', id: 34 };
is the exact equivalent of

```ts

  const example: {
    slug: `${string}_${number}`;
    id: number;
  } & { status?: [code: number, text: string] } = { slug: 'abc_34', id: 34 };

For TS-specific keywords like `satisfies`, there's a corresponding JSDoc keyword like @satisfies. Generics use @template.

Is there any specific feature you think is not supported? I'm sure I could work up a TS Playground example.

> Is there any specific feature you think is not supported

Yeah, uhm, most of what you've been posting? :). That JSDoc example above gives:

    ERROR: Unable to parse a tag's type expression for source file /Work/lol-jsdoc-why/index.js in line 1 with tag title "
    type" and text "{{  slug: `${string}_${number}`;  id: number;} & { status?: [code: number, text: string]; }}": Invalid type expre
    ssion "{  slug: `${string}_${number}`;  id: number;} & { status?: [code: number, text: string]; }": Expected "!", "$", "'", "(", 
    "*", ".", "...", "0", "?", "@", "Function", "\"", "\\", "_", "break", "case", "catch", "class", "const", "continue", "debugger", 
    "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "implements", "impor
    t", "in", "instanceof", "interface", "let", "new", "null", "package", "private", "protected", "public", "return", "static", "supe
    r", "switch", "this", "throw", "true", "try", "typeof", "undefined", "var", "void", "while", "with", "yield", "{", Unicode letter
     number, Unicode lowercase letter, Unicode modifier letter, Unicode other letter, Unicode titlecase letter, Unicode uppercase let
    ter, or [1-9] but "`" found.
Edit: Also, your first edit says Webpack switched from TypeScript to JavaScript, but Webpack source was never written in TypeScript.
We're talking about two different things here. All my examples work perfectly fine with TypeScript

https://www.typescriptlang.org/play/?#code/PQKhCgAIUgBAXAngB...

You are attempting to generate documentation from jsdoc comments using an npm package that is also called "jsdoc". Ofc in this case "JSDoc is not TypeScript". That package only supports the subset of JSDoc that is relevant to it. Though I believe you can use TypeDoc instead if you want to generate documentation from JSDoc that contains typescript types.

In the post I made it explicit that I'm talking about intellisense, developer tooling, type checking etc. You can run `tsc` to do typechecking on a project typed with JSDoc like the examples I've given throughout this thread just fine.

I guess the difference here is I'm coming at this from the perspective of "what is TypeScript used for. Can JSDoc comments substitute that". And the answer is almost completely yes.

Also tbh I've never met anyone that uses that package to generate API docs. I don't think it's a very modern package: https://github.com/jsdoc/jsdoc/issues/2129

Apologies, my first draft of that comment got deleted on a refresh (mobile) and my posted one left out how I'm probably being too pedantic: the official JSDoc is not TypeScript.

Your post is actually one of the more accurate ones compared to others that say "you don't need typescript" with the big caveat that you actually need a whole lot of the typescript ecosystem to make JSDoc work.

I just wish there was an official handover, or a more clear delineation between JSDoc and Typescript JSDoc Extensions.

I think you have a valuable point. I kinda purposely avoided explicitly defining what JSDoc is. Instead I'm relying on "the JSDoc we're all familiar with". I said in the post that if your IDE is giving you intellisense from JSDoc comments then you are almost certainly already using TypeScript. That's about as close as I got to defining the JSDoc I'm talking about

But given that JSDoc doesn't have any sort of formal spec, I think the distinction you're making is more of a historical than a technical one.

I’m curious how type checking is possible in a JDoc project. As far as I’m aware there’s no way to get type checking to work without tsc or a TypeScript LSP plugin.
That is exactly how it works. Any IDE providing you intellisense is using the TypeScript language service. That's why this article is called "JSDoc is TypeScript". If you see a red squiggly because of your JSDoc comment, you are almost certainly already using TypeScript (without any .ts files)
Ha! I see I elicited the copy/paste response I’ve seen elsewhere. The gp comment I was replying to implied a JSDoc only solution (“all in JSDoc”), but given the response, clearly they’re still relying on the TypeScript language service (aka lsp plugin) to achieve type checking inside their IDE.

Wishful thinking on my part that an alternative solution for JSDoc based type checking exists :)

Do you have a particular reason to care about the implementation details of your tooling's type checker?
Generally, no. Only in the case you had a requirement to exclusively use JavaScript as the programming language you might be in for an awkward time justifying that you added type checking to the project via the type checker component of TypeScript with JSDoc :)
Depends on your definition of "using" JavaScript. The main difference between common TypeScript and TS-based JSDoc is the need for an additional build step. Being able to ftp-upload your `.js` files and then be done with it is a remarkable advantage over Vite/Webpack/whatever in small to medium-sized projects. If editor based type support is sufficient to you (i.e. no headless checks), you won't need to install any TS packages at all, either. tsserver is still used in the background, but so are thousands of other binaries that keep your editor, OS and computer running, so I don't see that as an argument.