JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.
In this article, we’ll look at the best practices for writing documentation with JSDoc.
Top/File-Level Comments
A file may name things like a copyright notice, author information in the comments.
We may also include the description of the file contents if it doesn’t repeat what’s in the code.
Class Comments
A class may have its own comments with the description and the parameters.
For instance, we can write:
/**
* A class to store Fruit data
*/
class Fruit extends Food {
/**
* @param {string} name An argument for the name.
* @param {Array<number>} dimensions List of numbers for the
* dimensions.
*/
constructor(name, dimensions) {
// ...
}
};
We have a description of the class above the class.
And inside the class, we have a comment block to explain the items in the constructor.
Each parameter has its own explanation of what it holds and the type of them.
This way, we can use programs to help us create documentation if needed.
Enum Comments
We can write comments for an enum.
For instance, we can write:
/**
* Types of weight units.
* @enum {string}
*/
const WeightType = {
GRAM: 'gram',
POUND: 'type',
};
We added a comment for an enum that has a list of weight units.
The comment has an @enum tag to explain what each enum value’s type is.
In this example, they’re all strings.
Method and Function Comments
Like with classes and objects, we can add comments to methods.
For instance, we can write:
/** A class */
class FooClass extends BaseClass {
/**
* Operates on a FooClass instance and returns item.
* @param {!FooClass} foo Some object.
* @param {!OtherClass} other Another object.
* @return {boolean} Whether something occurred.
*/
doSomething(foo, other) { ... }
/** @override */
overriddenMethod(param) { ... }
}
In the code above, we have a comment for the clas at the top.
Then we have a comment block to describe what a method does.
In addition, we have an explosion of what each parameter can hold and the data type of them.
Also, we have the @override tag to explain that the method overrides a method of the parent class.
Likewise, we can have something similar in function.
For example, we can write:
/**
* A function that makes an object.
* @param {TYPE} arg
* @return {!TYPE2}
* @template TYPE
*/
function makeObject(arg) { ... }
We have a function that takes a given type of argument, so we write a comment to explain that.
Also, we have the @return tag to return some object of TYPE2 .
Property Comments
Also, we can add comments to properties.
For instance, we can write:
/** A class. */
class AClass {
/** @param {string=} arg */
constructor(arg = 'something') {
/** @const {string} */
this.arg = arg;
}
}
We have a class that has a constructor with some comments.
We added a comment for the constructor’s argument.
Also, we have another one for the instance variable itself.
We indicated that it’s constant with the @const tag.
Type Annotations
We add data type annotations after @param , @return , @this , and @type tags.
Also, we can add them optionally on @const , @export and any visibility tags.
Nullability
The modifiers ! and ? denote non-nullable and nullable respectively.
Also, we add type annotations for primitives, including string , numbner , boolean , symbol , undefined , and null .
Literal types of annotations include functions:
{function(...): ...}
and objects:
{{foo: string...}}
Reference types are UpperCamelCase.
Template Parameter Types
We should specific parameters in types.
For instance, we write:
const /** !Array<string> */ names = [];
if our array is a string array.
Conclusion
We can add comments for parameters, constructors, classes, and object properties.
Information like the type of them, if applicable, what a function returns, etc. can be added.
On top of a file, we can put information like a copyright notice or something like that.
There are also symbols for indicating nullability.