How to utilise JSDoc comment tags so that Visual Studio Code intellisense works great
Tags: javascript, vscode, jsdoc, programming
Published: 2021-07-16 06:09:59

---
title: How to utilise JSDoc comment tags so that Visual Studio Code intellisense works great
published: true
description: JSDoc is the standard for commenting in JavaScript code. Let's learn how we can utilise the same so that VS Code's intellisense works great!
tags: JavaScript, VSCode, JSDoc, Programming
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9swn6wki0orqdyq589k2.png
canonical_url: https://blog.shhdharmen.me/how-to-utilise-jsdoc-comment-tags-so-that-visual-studio-code-intellisense-works-great
---
## Types in JavaScript

JavaScript is a loosely typed and dynamic language. Variables in JavaScript are not directly associated with any particular value type, and any variable can be assigned (and re-assigned) values of all types:

```javascript
let foo = 42;    // foo is now a number
foo     = 'bar'; // foo is now a string
foo     = true;  // foo is now a boolean

```

## Intellisense in VS Code

Visual Studio Code's intellisense will only work, if it understands the `type` of of your code.

In above example, after you write first line, `let foo = 42; ` it will show you methods of a number:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1626372660432/JKt16SWHX.png)

But what if you assign a JSON, which is going to hold many properties like `id`, `createdOn`, etc.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1626372701424/76Qwg8gIF9.png)

It's also working fine. But, it's unlikely that your variable is going to hold values with initialization. So, now if you check for blank JSON, intellisense will stop working, because now VS code doesn't know the types.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1626372713349/nFnAUNqsN.png)

Without proper intellisense, we often make typos, call the method which doesn't exist or even try to access the properties of an objects by a random guess.

To handle such and more complex scenarios, and make sure intellisense works right for those, we will use [JSDoc](https://jsdoc.app/)'s `@param`, `@type` and `@typedef` block tags.

## JSDoc to the rescue

JSDoc comes with lots of tags, you can checkout them all on it's website: <https://jsdoc.app/>. But for this article, we are going to focus on below 3 tags:

1. [`@param`](https://jsdoc.app/tags-param.html)
2. [`@type`](https://jsdoc.app/tags-type.html)
3. [`@typedef`](https://jsdoc.app/tags-typedef.html)

### `@param`

> The `@param` tag provides the name, type, and description of a function parameter.
> 
> The `@param` tag requires you to specify the name of the parameter you are documenting. You can also include the parameter's type, enclosed in curly brackets, and a description of the parameter.
> 
> - [Source](https://jsdoc.app/tags-param.html#overview)

Let's look at some examples.

```javascript
/**
 * @param {string} somebody
 */
function sayHello(somebody) {
    alert('Hello ' + somebody);
}
```

After above code, VS code's intellisense will work great whenever you try to call `sayHello`:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1626372756661/aJe_pj1jm.png)

You can look at more examples at <https://jsdoc.app/tags-param.html#examples>.

### `@type`

> The `@type` tag allows you to provide a type expression identifying the type of value that a symbol may contain, or the type of value returned by a function. You can also include type expressions with many other JSDoc tags, such as the `@param` tag.
>
> A type expression can include the JSDoc namepath to a symbol (for example, `myNamespace.MyClass`); a built-in JavaScript type (for example, `string`); or a combination of these. You can use any [Google Closure Compiler type expression](https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#type-expressions), as well as several other formats that are specific to JSDoc.
>
> - [Source](https://jsdoc.app/tags-type.html#overview)

Let's take a look at example:

```javascript
/** @type {Array} */
var foo;
```

For above code, typing `foo.` will load all `Array`'s properties and methods:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1626372772162/tMU-pXRxg.png)

More examples at <https://jsdoc.app/tags-type.html#examples>

### `@typedef`

> The `@typedef` tag is useful for documenting custom types, particularly if you wish to refer to them repeatedly. These types can then be used within other tags expecting a type, such as `@type` or `@param`.
>
> - [Source](https://jsdoc.app/tags-typedef.html#overview)

This tag is really helpful, it helps us to shape any complex type. Let's take a look at example.

This example defines a more complex type, an object with several properties, and sets its namepath so it will be displayed along with the class that uses the type. Because the type definition is not actually exposed by the function, it is customary to document the type definition as an inner member.

```javascript
// src/toast.js

/**
 * @typedef {Object} Toast
 * @property {string} id
 * @property {boolean} closed - Indicates whether user has close the toast.
 * @property {Date} generatedOn - Indicates when the toast was generated.
 * @property {string} message - toast content.
 * @property {"warn" | "info"} type -  Indicates type of toast.
 * Also useful to show different icons.
 */

/**
 * A function for showing toast
 * @param {Toast} toast - {@link toast} object
 * containing all components of the toast.
 */
export function showToast(toast) {}

```

Here is the breakdown of above code:

1. The first line:
   1. We first indicated that we want to create a custom type using `@typedef` tag
   2. Then we indicated that it's going to be an `Object`. You can also create simpler custom type using primitive date types, for example `string` or `number`.
   3. And lastly, we named this type as `Toast`
2. Now, as `Toast` is going to be an `Object`, in rest of the comments, we defined what are it's `properties` going to be using `@property` tag. You can learn more about `@property` tag [here](https://jsdoc.app/tags-property.html).

Now if you try to call `showToast`, VS code will do it's magic:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1626372818836/rFMwqFCUy.png)

But, this is not enough. In practical scenarios, you would be generating `Toast`s in different files and calling `showToast` from there. You can export and import `showToast` in other files, but what about `Toast` type definition?

You can also import type definition the same way you import bindings from another module. But as types are created in comments, you need import them in comments:

```javascript
// src/home.js

import { showToast } from "./toast";

/**
 * @returns {import("./toast").Toast[]}
 */
function getToasts() {}

const allToasts = getToasts();

allToasts.forEach((toast) => {
  showToast(toast);
});

```

Just to emphasis, here's how we imported `Toast` type definition:

```javascript
/**
 * @returns {import("./toast").Toast[]}
 */
```

You can read more about `@typedef` at <https://jsdoc.app/tags-typedef.html>.

## Conclusion

We learned how JSDoc block tags, `@param`, `@type` and `@typedef` can help us to achieve maximum out of VS Code's intellisense and code faster without getting into un-wanted issues.

That's it! Thanks for reading. Let me know your thoughts and feedbacks in comments section.

And yes, always believe in yourself 🌅

![joshua-earle-JAwzCW0JpIw-unsplash.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1626373183525/KRCCwEHxN.jpeg)

<small>Photo by <a href="https://unsplash.com/@joshuaearle?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Joshua Earle</a> on <a href="https://unsplash.com/s/photos/faith?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
</small>