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;
}
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
*/
And then you can apply that interface to an object using the @type
annotation:
/** @type {Customer} */
const theCustomer = { ... }
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;
}
And then in your .js
file you can import those types:
/**
* @typedef { import("./models").Customer } Customer
*/
/** @type {Customer} */
const theCustomer = { ... }
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)