An example project showcasing type-safe JavaScript using TS-compatible JSDoc
The JS community has many misconceptions about the fitness-for-purpose of TS-compatible JSDoc, and I'd wager this stems from not knowing how to set it up properly.
I've heard things like:
- "You get no intellisense/tab-completion in your editor"
- "It's not typesafe" or "there's intellisense, but no type checking"
- "You can't generate type declarations"
- "You can't use the types in other projects"
The above claims are false.
These two claims are partially true:
-
"X is impossible in JSDoc": The things that are impossible in JSDoc are mainly things you'd typically do in
.d.ts
files, like ambient module declarations, declaration merging, etc. I know of no other major feature that is impossible in JSDoc (correct me if I'm wrong) other than bulk re-exports (e.g.,export type * from './something.js'
; see Microsoft/Typescript#48104).ℹ️ Tip
Note that it is trivial to drop a
.d.ts
file into your project for the few things that are impossible in JSDoc--I do this myself to declare types for packages which ship none. -
"It's too verbose": Some things are objectively more verbose (such as type assertions). Complex conditional or mapped types are nicer to write in TS than in a
@typedef
. The introduction of@import
in TS v5.5 mitigated a significant usability headache.
Features of this example include:
- Type safety in the IDE and in CI (check all types via
npm run lint:types
) - Optional generation of
.d.ts
files (vianpm run build:declarations
) - EcmaScript Modules
- All files explained in detailed comments
This could be used as a scaffold, but I think it's probably fine as just reference material for applying to your own projects. To that end:
- Look at the files in
src/
to see how things work.
If you do want to use it as a scaffold, you can:
- Clone this repo.
- Run
npm install
. - Run
npm run build:declarations
to generate type declarations (seetypes/
for output) - Run
npm run lint:types
to check types.
See demo for a project that shows how to consume the generated declarations.
In other words, why not just use TypeScript?
- Even if you're using another build tool, adding
tsc
to the mix often adds complexity. - Avoids the overhead of a build step during your development cycle (especially when you have no other build tooling).
- The TS compiler generates code that does not meet your needs (rare, but happens to be my use case).
- You could Ask Rich Harris of Svelte (archive, original interview)
I actually prefer TypeScript in my personal projects, but I have used JSDoc in many professional projects where TS was not an option. That said, there are few drawbacks to plopping types-only .ts
sources into an otherwise pure-JS project (which this repo illustrates), and I have so in each of the aforementioned professional projects (to wild success, of course).
In my experience, a correctly-configured project gets you 95% of the benefits of using TS alone, and any drawbacks are tolerable.
Copyright © 2025 Christopher "boneskull" Hiller. Licensed Zero-Clause BSD.