DEV Community

Cover image for How to Write TypeScript Interfaces in JSDoc Comments
Wes
Wes

Posted on • Edited on • Originally published at goulet.dev

How to Write TypeScript Interfaces in JSDoc Comments

Updated 2023-07-23 to clarify that jsdoc comments support object types, not interfaces. Thanks to Matt Pocock for the pointer.

I like writing web apps without any build step, just vanilla .js files. But I still like the type-checking that TypeScript provides. Thankfully TypeScript supports type-checking .js files via JSDoc comments.

But how do you write out interfaces without a .ts file? The tl;dr is you can write an object type in a JSDoc comment, or you can write an interface in a .d.ts file and import that into your .js file. Let's dig into each option.

Interfaces in a .ts file

First, let's look at an example in a .ts file.

interface Address {
    street: string;
    city: string;
    zip: number;
}

interface Customer {
    name: sting;
    email: string;
    address: Address;
}
Enter fullscreen mode Exit fullscreen mode

Option 1: Object Types in a JSDoc comment

An object type isn't exactly an interface, but for most use cases it behaves the same way.

The main difference is interfaces support declaration merging but object types do not.

Writing those same interfaces in a .js file would look like:

/**
 * @typedef Address
 * @prop {string} street The street
 * @prop {string} city The City
 * @prop {number} zip The zip code
 *
 * @typedef Customer
 * @prop {string} name The Customer's name
 * @prop {string} email The Customer's email
 * @prop {Address} address The Customer's address
 */
Enter fullscreen mode Exit fullscreen mode

And then you can apply that interface to an object using the @type annotation:

/** @type {Customer} */
const theCustomer = { ... }
Enter fullscreen mode Exit fullscreen mode

Boom 💥 now you've got type-checking and intellisense on your data model right in a vanilla .js file.

Option 2: import interfaces from a .d.ts file

The other option to define interfaces is to put them in a .d.ts file and import that into you .js file.

// models.d.ts

export interface Address {
    street: string;
    city: string;
    zip: number;
}

export interface Customer {
    name: sting;
    email: string;
    address: Address;
}
Enter fullscreen mode Exit fullscreen mode

And then in your .js file you can import those types:

/**
 * @typedef { import("./models").Customer } Customer
 */

 /** @type {Customer} */
const theCustomer = { ... }
Enter fullscreen mode Exit fullscreen mode

This is my preferred approach as I find writing types in .d.ts files to be more terse than writing types out in jsdoc comments. But I like having both options available to use interchangeably.

Related Posts

Hopefully you found this post helpful, if you have any questions you can find me on Twitter.

Top comments (0)