top | item 46266102

JSDoc is TypeScript

208 points| culi | 2 months ago |culi.bearblog.dev

275 comments

order
[+] Waterluvian|2 months ago|reply
A few things I've come to personally believe after spending years developing web and robotics software in Python/JavaScript then spending years having to maintain while constantly adding new features and dealing with company pivots:

- The types exist whether you write them down or not.

- If they're not written down, they're written down in your head.

- Your head is very volatile and hard for others to access.

- Typing is an incredibly good form of documentation.

- JSDoc and TypeScript are standards/formats for typing. Like any tools, they both have advantages and disadvantages. Neither is objectively better than the other.

- Make informed decisions on how you'll describe your types, and then be consistent and unsurprising.

- A type checker is the computer saying, "okay then, prove it" about your program's type validity.

- Not every program benefits from the same amount of "prove it."

- Too much can be as bad as too little. You're wasting resources proving throwaway code.

- I like languages that let you decide how much you need to "prove it."

[+] Culonavirus|2 months ago|reply
> Your head is very volatile and hard for others to access.

One of the lessons you learn while doing this job is that "others" includes "yourself in the future".

(Of course people will tell you this way before you find out yourself, but what do they know...)

[+] john01dav|2 months ago|reply
> - I like languages that let you decide how much you need to "prove it."

Rust is known for being very "prove it," as you put it, but I think that it is not, and it exposes a weakness in your perspective here. In particular, Rust lets you be lax about types (Any) or other proved constraints (borrow checker bypass by unsafe, Arc, or cloning), but it forces you to decide how the unproven constraints are handled (ranging from undefined behavior to doing what you probably want with performance trade-offs). A langauge that simply lets you not prove it still must choose one of these approaches to run, but you will be less aware of what is chosen and unable to pick the right one for your use case. Writing something with, for example, Arc, .clone(), or Any is almost as easy as writing it in something like Python at the start (just arbitrarily pick one approach and go with it), but you get the aforementioned advantages and it scales better (the reader can instantly see (instead of dredging through the code to try to figure it out) "oh, this could be any type" or "oh, this is taken by ownership, so no spooky action at a distance is likely").

[+] culi|2 months ago|reply
> JSDoc and TypeScript are standards/formats for typing. Like any tools, they both have advantages and disadvantages. Neither is objectively better than the other.

Agreed. Just to clarify, my intentions with this post weren't to advocate for one over the other. Just to point out that they are the same thing. They are both TypeScript.

[+] jama211|2 months ago|reply
And if your boss is the type to pivot way too often and want it done yesterday, then they don’t deserve code that is prove in the right places so you just get an LLM to add typing to everything after the fact…
[+] christophilus|2 months ago|reply
Yeah. I learned this lesson 25 years ago in university. SQL, Lisp, and whatever scripting language I was learning at the time were always much harder to reason about vs statically typed languages— particularly in team projects. Over the years, I’ve gotten comfortable with SQL, but I always prefer static typing when I can get it.
[+] dominicrose|2 months ago|reply
> The types exist whether you write them down or not

That's easy to say when we're talking about primitive arguments in private functions, or primitive local variables, but let's not ignore the fact that it takes much more work to write a C# program than a Ruby program for instance.

We can see that by looking at a vanillajs library's typescript typings that were created after the js library when typescript didn't exist. The types are insanely complex and if you get one type wrong you can break compilation of some library user's program (its happened to me).

That being said I'm aware that dynamic programming languages are a "use at your own risk" type of language.

[+] scotty79|2 months ago|reply
> I like languages that let you decide how much you need to "prove it."

I love that too. Are there any other languages than TS that have this as a core design feature?

[+] user3939382|2 months ago|reply
I'll take a more definite position. Build pipelines are the devil. Every square inch of surface complexity you add to whatever you're doing, you will pay for it. If there's a way to get the benefits without the build step, that's your choice. You may need runtime type enforcement, so that's not JSDoc, and you're doing that with... JS so that's already suspicious but the use case def exists. JS, the DOM, HTTP, this whole stack is garbage at this point so arguing about the type system is a little idk hard to care about personally. I have a solution that lets you discard most of the web stack, that's more interesting to me.
[+] emseetech|2 months ago|reply
I'm a fan of anything that allows me to build with javascript that doesn't require a build step.

Modern HTML/CSS with Web Components and JSDoc is underrated. Not for everyone but should be more in the running for a modern frontend stack than it is.

[+] bobbylarrybobby|2 months ago|reply
On the one hand I can see the appeal of not having a build step. On the other, given how many different parts of the web dev pipeline require one, it seems very tricky to get all of your dependencies to be build-step-free. And with things like HMR the cost of a build step is much ameliorated.
[+] odie5533|2 months ago|reply
I have not written a line of JavaScript that got shipped as-is in probably a decade. It always goes through Vite or Webpack. So the benefit of JS without a build step is of no benefit to me.
[+] junon|2 months ago|reply
Webcomponents are a pain in the ass to make, though. That is, sufficiently complex ones. I wish there was an easier way.
[+] auxiliarymoose|2 months ago|reply
Agreed on native HTML+CSS+JSDoc. An advantage in my use-cases is that built-in browser dev tools become fluid to use. View a network request, click to the initiator directly in your source code, add breakpoints and step without getting thrown into library internals, edit code and data in memory to verify assumptions & fixes, etc.

Especially helpful as applications become larger and a debugger becomes necessary to efficiently track down and fix problems.

[+] winrid|2 months ago|reply
TS is worth the build step.
[+] pjmlp|2 months ago|reply
I was already doing that in 2010, with the JSDoc tooling in Eclipse and Netbeans back then.

However I don't get to dictate fashion in developer stacks.

[+] fergie|2 months ago|reply
> Modern HTML/CSS with Web Components and JSDoc is underrated.

I've been a front end developer for 25 years. This is also my opinion.

[+] mmcnl|2 months ago|reply
You don't need a build step anymore with TypeScript since Node 24.
[+] mmcromp|2 months ago|reply
Why? The half a second for the HMR is taking up too much your day?
[+] kellengreen|2 months ago|reply
Came here to write this exact sentiment. Not everything needs a massive build pipeline.
[+] etoxin|2 months ago|reply
So, some history. When SPA's started to boom on the web JSDoc was a life saver for typing. Application state was getting more complex. We needed more guard rails.

Then Google Closure Compiler came along which added type safety via JSDOC and TS came along with (TS)JSDoc support and it's own TS syntax.

The community chose native TS and Google Closure compiler slipped away into the background.

So (TS)JSDoc support is a relic from when Microsoft was trying to get market share from Google.

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.

Today I use TS. I also use plain JSDoc for documentation. e.g. @link and @see for docs. Or @deprecated when I'm flagging a method to be removed. @example for a quick look up of how to use a component.

TS and plain JSDoc are both important together. But (TS)JSDoc alone, is a relic of the past.

[+] culi|2 months ago|reply
> 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.

[+] johnfn|2 months ago|reply
The article is an explicit response to the point you’re making.
[+] phil294|2 months ago|reply
> So (TS)JSDoc support is a relic from when Microsoft was trying to get market share from Google.

> 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.

None of that is true! Please don't share misinformation without looking it up first.

[+] mirekrusin|2 months ago|reply
1. there are plenty things you can't express in jsdoc but can in typescript, flow did the right thing here where you have access to full language, not sure why typescript never did it, they could, with the same syntax flow is using

2. you can have navigation that goes to typescript file instead of definition, just arrange your exports in package.json correctly (first ones take precedence)

[+] culi|2 months ago|reply
Well I'd love to hear some concrete examples if you have any on hand! I was of the same opinion as you until I refactored a project of mine to use JSDoc.

Since any TypeScript type can be expressed in JSDoc, I imagine you're mostly thinking of generics. At least that was my main sticking point. JSDoc does actually have generic slots with the @template tag. Actually using them in practice is a little unintuitive but involves typing the return type. E.g. for a function it'd look like this:

  /** @type {ReturnType<typeof useState<Book[]>>} */
  const [books, setBooks] = useState();
[+] creatonez|2 months ago|reply
> there are plenty things you can't express in jsdoc but can in typescript

This isn't really true anymore, they have systematically added pretty much every type system feature to the JSDoc-like syntax.

[+] crummy|2 months ago|reply
> For packages typed with JSDoc, CTRL/CMD clicking on a function will take you to actual code rather than a type declarations file. I much prefer this experience as a dev.

ok i didn't think about this, that's an underrated benefit

[+] zackify|2 months ago|reply
5 years ago I was at a meet up and the guy talking was saying how if you don't like typescript these jsdocs are the way to go. Had to explain to my employer attending that it is still typescript. Didn't seem to believe me and was super against typescript but not jsdocs lol
[+] llimllib|2 months ago|reply
counterpoint: JSDoc is not typescript

If you define a type in a file with @typedef, it is automatically exported and there is nothing you can do to control that: https://github.com/microsoft/TypeScript/issues/46011

I tried making a library this way and lacking control over the visibility of the exported types was really painful; it made my intellisense awful because every type I defined at the root was exported from the library

[+] pjmlp|2 months ago|reply
TypeScript won over the alternatives, exactly because it is only a type checker, and not a new language.

Granted they initially weren't down that path, but they course corrected it on time, and not much people use stuff like enums in new code.

[+] akst|2 months ago|reply
I'm actually using JSTypes in app, I don't mind it.

I choose to use it because I didn't want to deal with a build step for a smaller project. The project has grown and I am looking at adding a build step for bundling but still not too worried about using JSDoc over TS.

This might be my config, but one thing that does annoy me is whenever I define a lambda, I need to add an doc type. I guess if that's disincentivising me from writing lambdas maybe I should just add a TS compile step lol.

----------------------

Here's an example - I got some config typed with this function https://github.com/AKST/analysis-notebook/blob/c9fea8b465317... - Here's the type https://github.com/AKST/analysis-notebook/blob/c9fea8b465317... - And here's something to generate a more complicated type for defining config knobs https://github.com/AKST/analysis-notebook/blob/c9fea8b465317...

[+] g947o|2 months ago|reply
I work in a codebase that unfortunately does not support TypeScript. I use JSDoc extensively, although not with type check enabled (due to various limitations). I also work on other projects with TypeScript. My own experience is that the DX with "real" TypeScript is much, much better than JavaScript with JSDoc, without question. JavaScript with JSDoc is much more verbose, with a lot of limitations when types get long or complex compared to TypeScript. The official TypeScript language service also does not provide the same level of support in very subtle ways.

Basically, the fact that it works does not mean it works well, and I don't recommend anyone going in this other direction unless they understand what they are getting into.

[+] CSSer|2 months ago|reply
> For packages typed with JSDoc, CTRL/CMD clicking on a function will take you to actual code rather than a type declarations file. I much prefer this experience as a dev.

More broadly, this is the default behavior of JS even without JSDoc blocks, and it ought to be the default behavior everywhere, including TS. I'm not alone in this sentiment, but it's incredibly contentious. There's been an open GH issue about it with hundreds of replies for years. I have no idea why they can't just pick a different shortcut for viewing types and call it a day. They'd be doing the entire ecosystem a favor.

[+] auggierose|2 months ago|reply
Been there, tried that. When starting to write JavaScript in anger 3 or 4 years ago, I started out with JSDoc, because my impression was also, hey, that is like TypeScript, but closer to the metal and maybe with less magic. A few months in I realised that TypeScript is just a better and more well-rounded implementation of what JSDoc has to offer (I don't remember now, but there were annoying things that you would expect would work in JSDoc, but didn't quite).

Just use TypeScript.

[+] w3news|2 months ago|reply
Thanks, I use JSDoc for several years, and also validate it with Typescript. So I just write plain Javascript with JSDoc, with no build step. Typescript only validates the types, and not transforming the code. Did you also know that you can import Typescript types/interfaces in JSDoc? So for me typescript is not a language anymore, I use only the tool to validate the types.

Best thing for me was not removing the code transformation (convert ts to js), but separate runtime code with documentation code, like the types. Gives you much more clear insight that the types you write to describe what you expect the type will be is not forced on runtime, but is just for you as developer to know it. And when you validate the input is the right type, it is much more clear that it is the runtime type validation.

You can still use JSDoc in your typescript files, but why do you want to do that? There is no reason to do that.

So using JSDoc or Type Annotation, both works the same, same benefits, it is only personal preferences. Both have its pros and cons. For me the JSDoc has more benefits. Some other people prefer annotations. But there is not 1 that is better in controlling the types, has more options. (Also the enum can be done if you are using JSDoc, but is a little different)

[+] supernes|2 months ago|reply
> You can still use JSDoc in your typescript files, but why do you want to do that?

JSDoc is more than type annotations. I use it for method and parameter descriptions, deprecation notices, inline examples, etc even in TS files.

[+] sureglymop|2 months ago|reply
A somewhat related thing programmers must understand is that whether you write typescript, JSX, .astro or .svelte files, you are technically not writing JavaScript.

You should occasionally look at the build artifacts of your framework but also ask yourself whether it is worth it to write code that may not represent what actually ends up being executed.

Lately I just use vite with no starter template but with web components and css modules. It at least feels more convenient than using any framework or library.

[+] jcbhmr|2 months ago|reply
JSDoc works great for buildless application setups! One downside is that if you publish a library to npm you still need a build step to generate .d.ts files from your JSDoc type annotations so that npm shows a "TS" badge on the npm package page. This also seems to apply to VSCode's intellisense which keeps trying to poke you to "try to install @types/jsdoc-typed-package to get type information". Other JS ecosystem tooling also doesn't seem to process JSDoc types at all such as jsdocs.io or tsdocs.dev. So for libraries we're stuck with .d.ts generation via "tsc --allowJs --checkJs --declaration ..." even if it's all JS.

npm displays packages with bundled TypeScript declarations https://github.blog/changelog/2020-12-16-npm-displays-packag...

JSDoc-typed node modules require special configuration in consumers to be useful https://github.com/microsoft/TypeScript/issues/19145

[+] conartist6|2 months ago|reply
I still think that JS is very much not TS. Most TS code assumes you never need to check for errors because the type checker proves they can't happen.

Then, paradoxically, with no error checking at runtime, it becomes fully possible for JS code to call into TS code in a way that breaks the shit out of the TS compiler's assumptions. In philosophy then TS and JS are as incompatible as GPL and EULA

[+] auxiliarymoose|2 months ago|reply
This is how I develop web software, and I've found it productive and maintainable.

A bonus of this approach is that it clearly delineates what type information is available at runtime, vs what type information is just a comment. (especially useful when working with serialized data).

I also like that it generally means all of the preconditions and postconditions for functions are in a single place (both the prose and the technical information are in the JSDoc comment), keeping the code itself low-noise and boiled down to its essence, and providing a natural place to write example inputs and outputs to guide usage.

As for generic types, I use them extensively, and this is made less verbose e.g. on function calls by using an @type annotation on the function which accepts a TypeScript signature without needing separate @template + @param annotations.

It's awesome stuff, and I'm happy that TypeScript works so well with JSDoc!

[+] Brysonbw|2 months ago|reply
I'm a big advocate for explicit type annotations in code. Likewise, either or is good with me. However, these days I lean towards using JSDoc only because I prefer not to add typescript lib and an additional build step just to get type safety in a project.

Also, you can use both (if that's what you prefer).