Have your Cake and Eat It Too: JSDoc for Typing JavaScript without Compiling
The typed vs untyped debate is one that comes and goes depending on the era and stack. For example, I started with Java (typed), then moved to JavaScript (untyped), witnessed some horrors, and returned to typed (TypeScript).
So, who takes the spotlight here? JavaScript, as hinted by the title.
To Type or Not to Type
Getting started with untyped languages (JavaScript, Python, etc.) often comes with phrases like “more freedom” and “less boilerplate.”
And it is true, an untyped language can be written in fewer lines, and it lets you mix types within the same variable. It is like riding a motorcycle without a helmet — it feels nice until you need to be buried in a closed casket.
This is my take, and I stand by it: For serious projects, “untyped” languages do more harm than good.
TypeScript emerged at a time when JavaScript was consolidating itself as a language, leaving behind its role of just being used for simple and short scripts on web pages. When writing code files after files, especially with multiple developers collaborating, typing became essential to avoid grotesque, hard-to-detect errors that only surface when in production.
TypeScript adds syntax for defining data types, but it also introduces the need to “compile” the code. Suddenly, code that used to just run now requires extra steps, which often add complexity to both development and deployment. This complexity, while manageable with tools and processes, is still present.
With Python, I came across the idea of “type hint.” Instead of requiring the language’s syntax to define data types, you can simply add “hints” to display what type is expected at a given point.
Just to clarify, this does not replace proper type syntax; it is a way to solve the problem without changing the language definition itself.
What is JSDoc?
JSDoc is an (old) comment format that inherits from JavaDoc the idea of defining standard information about different parts of a package, file, function, class, etc., so that other tools (like IDEs) can use it.
For example, if I add documentation for each parameter in a function, the IDE can explain what is expected at that spot when you hover over it. This is super helpful to understand how the different elements we have available in code work.
JSDoc is based on JavaDoc, but it adds a way to declare the type that each element should have, whether it is a parameter, function return value, etc.
So far, so good. An IDE can understand what each element needs, but it does not validate if something matches the documentation. greetPerson could be called with an array of floating-point numbers as a first parameter, and when you run it, you will find that the array does not understand “firstName”.
Do you know how to create a “tsconfig.json” file with your project/module configuration in TypeScript? Well, here, you do the same thing, but with a “jsconfig.json” file.
…The same thing.
Yes, ironically, the jsconfig.json format is borrowed from TypeScript.
Here is a simple example of a jsconfig.json file:
A moderately complex IDE should be able to read this file and display type errors based solely on the defined JSDocs, and the resulting code should run without the need to compile anything. It even allows you to import TypeScript types for this checking!
Conclusion
The tone of this article is pretty pro-JSDoc, right? Well, here comes the downside. Js files are going to end up with a lot of comments.
Many of them will be well-written: every function should document its format and functionality. But even between the lines, you will find comments like /** @type string[] */ to indicate that the variable below should hold an array of strings.
With TypeScript, you can type the code without too many comments. It still needs to be compiled, but nowadays there are tools that make live, selective compilation easier, and code is often processed to minify, uglify, and postprocess it, making TypeScript compilation just another step.
So, in conclusion, what is better? TypeScript or JSDoc typing?
It depends on the use. Personally, I will continue using TypeScript, since even though the configuration can sometimes cause issues, it is more mainstream, and the code is more concrete. Adding JSDoc to document (not type) classes and functions is part of a neat development process.
And why all this talk about JSDoc for typing? Because sometimes we really need to write code that cannot be post-processed, like when defining processes or steps for tools like Auth0. In these cases, this is an alternative to consider.