Skip to content

JSDoc and Type Checking

In the world of JavaScript and TypeScript, documentation and type checking are crucial for maintaining clean and readable code, especially in large projects. JSDoc, a documentation syntax for JavaScript, and TypeScript’s type checking capabilities are powerful tools in a developer’s arsenal. This article explores JSDoc’s role in documenting JavaScript code and how TypeScript enhances JavaScript with static type checking.

What is JSDoc?

JSDoc is a popular documentation syntax for JavaScript. It allows developers to annotate their JavaScript code with comments that describe the structure and behavior of the code. These comments can include information about functions, parameters, return types, and more. Tools can read these annotations to generate HTML documentation pages or provide enhanced code intelligence in editors.

Key Features of JSDoc:

  • Function and Parameter Descriptions: Clearly describe what a function does and the role of each parameter
  • Type Annotations: Specify the types of parameters and return values
  • Class and Method Documentation: Document classes and their methods, providing insights into object-oriented structures
  • Tag-based Syntax: Utilize a variety of tags like @param, @return, and @class for structured documentation

Basic JSDoc Examples

Function with parameters:

/**
 * Adds two numbers.
 * @param {number} a - The first number.
 * @param {number} b - The second number.
 * @return {number} The sum of the two numbers.
 */
function add(a, b) {
    return a + b;
}

Variable type annotations:

/** @type {number} */
let a = 1;

/** @type {string} */
let b = "2";

/** @type {Array<string>} */
let names = ["Alice", "Bob", "Charlie"];

/** @type  { {name: string, age: number}} */
let person = { name: "John", age: 30 };

Common JSDoc Tags

@typedef - Define custom types:

/**
 * @typedef {Object} User
 * @property {string} name - The user's name
 * @property {number} age - The user's age
 * @property {string} email - The user's email address
 */

/**
 * Creates a new user.
 * @param {string} name
 * @param {number} age
 * @param {string} email
 * @return {User}
 */
function createUser(name, age, email) {
    return { name, age, email };
}

@callback - Define function types:

/**
 * @callback CompareFunction
 * @param {number} a
 * @param {number} b
 * @return {number}
 */

/**
 * Sorts an array of numbers.
 * @param {Array<number>} arr - The array to sort
 * @param {CompareFunction} compareFn - The comparison function
 * @return {Array<number>}
 */
function sortNumbers(arr, compareFn) {
    return arr.sort(compareFn);
}

@class and @constructor:

/**
 * Represents a person.
 * @class
 */
class Person {
    /**
     * Creates a new Person.
     * @constructor
     * @param {string} name - The person's name
     * @param {number} age - The person's age
     */
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    /**
     * Gets the person's name.
     * @return {string} The person's name
     */
    getName() {
        return this.name;
    }
}

Type Checking with TypeScript

TypeScript, a superset of JavaScript, brings static type checking to the language. It allows developers to define types for variables, function parameters, return values, and more. TypeScript’s compiler checks these types at compile time, catching common errors before the code is executed.

Advantages of TypeScript’s Type Checking:

  • Early Error Detection: Identify type-related errors during development, not in production
  • Code Readability: Type annotations make the code self-documenting, clarifying the developer’s intent
  • Refactoring Safety: Safely refactor code with confidence that type contracts are maintained
  • Intelligent Code Completion: Enhanced editor support with autocompletion and inline documentation

Integrating JSDoc with TypeScript

While TypeScript inherently supports type annotations, JSDoc can be integrated with TypeScript for projects that prefer to stay closer to plain JavaScript. TypeScript understands JSDoc annotations, allowing developers to enjoy type checking without fully converting to TypeScript syntax.

TypeScript can infer types from JSDoc comments. This feature is beneficial for projects where TypeScript is not fully adopted, or for gradual migration from JavaScript to TypeScript.

Example of JSDoc with TypeScript Type Checking:

/**
 * Multiplies two numbers.
 * @param {number} a - The first number.
 * @param {number} b - The second number.
 * @return {number} The product of the two numbers.
 */
function multiply(a, b) {
    return a * b;
}
// TypeScript can infer the types from the JSDoc comments

Adding Type Checking by Installing TypeScript Locally

To enhance your JavaScript project with TypeScript’s type checking, you can install TypeScript locally in your project and add a tsconfig.json file. This setup provides the benefits of TypeScript’s type system, including error detection and intelligent coding assistance, while maintaining your existing JavaScript codebase.

Steps to Install TypeScript and Configure tsconfig.json:

  1. Install TypeScript: Run the following command in your project directory:

       npm install --save-dev typescript
    

  2. Create tsconfig.json: Create a tsconfig.json file in your project directory with the following contents:

       {
           "compilerOptions": {
               "target": "es6",
               "strict": true,
               "checkJs": true,
               "allowJs": true,
               "strictNullChecks": false
           }
       }
    

Note

The checkJs and allowJs options enable type checking for JavaScript files. The strictNullChecks option is disabled to allow for more flexible type checking. For more information about tsconfig.json, see the TypeScript documentation.

Now you can add type annotations to your JavaScript code and TypeScript will check them at compile time.

VSCode Integration

VSCode has built-in support for JSDoc and TypeScript. Once you have a tsconfig.json file with checkJs enabled, VSCode will:

  • Show type errors inline as you code
  • Provide intelligent code completion
  • Display parameter hints and documentation
  • Enable “Go to Definition” functionality
  • Offer quick fixes for common issues

You can control the type checking behavior with special comments:

// @ts-check - Enable type checking for this file
// @ts-nocheck - Disable type checking for this file
// @ts-ignore - Ignore errors on the next line
// @ts-expect-error - Expect an error on the next line (useful in tests)

Example with Type Checking Enabled:

// @ts-check

/**
 * @param {string} name
 * @param {number} age
 */
function greet(name, age) {
    console.log(`Hello ${name}, you are ${age} years old`);
}

greet("Alice", 30);      // ✅ OK
greet("Bob", "thirty");  // ❌ Error: Argument of type 'string' is not assignable to parameter of type 'number'

Limitations of JSDoc

While JSDoc is powerful, it has some limitations compared to full TypeScript:

  • Verbose syntax: JSDoc comments can become lengthy for complex types
  • Limited type features: Some advanced TypeScript features aren’t available in JSDoc
  • No runtime type checking: Types are only checked at development time, not runtime
  • Inference limitations: Type inference isn’t as powerful as native TypeScript
  • Refactoring support: Not as robust as TypeScript’s built-in refactoring tools

For large projects or teams heavily invested in types, full TypeScript may be a better choice. JSDoc is excellent for:

  • Adding types to existing JavaScript projects
  • Projects where full TypeScript adoption isn’t feasible
  • Libraries that want to provide type information without TypeScript dependency
  • Gradual migration to TypeScript

Summary

JSDoc and TypeScript type checking provide powerful tools for improving JavaScript code quality and maintainability.

Key Takeaways

JSDoc:

  • Documentation syntax for JavaScript using special comments
  • Provides type annotations without changing JavaScript syntax
  • Supports tags like @param, @return, @typedef, @callback
  • Generate HTML documentation from comments
  • Works seamlessly with TypeScript’s type checker

TypeScript Integration:

  • TypeScript understands JSDoc annotations
  • Enable type checking with checkJs in tsconfig.json
  • Get type safety without converting to TypeScript syntax
  • Ideal for gradual migration or hybrid projects

VSCode Support:

  • Built-in JSDoc and TypeScript support
  • Inline error reporting and code completion
  • Use @ts-check to enable file-level type checking
  • Special comments for controlling type checking behavior

When to Use:

  • JSDoc: Existing JavaScript projects, gradual adoption, library authors
  • Full TypeScript: New projects, heavy type usage, large teams
  • Hybrid approach: Start with JSDoc, migrate critical parts to TypeScript

Best Practices:

  • Document all public APIs with JSDoc
  • Use @typedef for complex types
  • Enable checkJs for projects with JSDoc annotations
  • Be consistent with documentation style
  • Use type checking to catch errors early

JSDoc provides a practical middle ground between untyped JavaScript and full TypeScript, offering type safety and better tooling without requiring a complete rewrite of existing code.