Your config files should be typechecked

aka, How to use the power of Typescript for your Prettier, ESLint and other config files

Jan 12, 2022 ยท programming, javascript

Or maybe not, whatever fits your needs. Personally, I think that definitely not enough people are using TypeScript for their config files, or maybe not a lot of people know that you even can in the first place!

Disclaimer: This article is somewhat severely outdated, as most of the tools mentioned now support using .ts files directly, or have types accessible easily, but I'm keeping it around for posterity.


Luckily, we're entering an era of many projects having their config files typechecked as a first-class option, for instance FaviconVite supports it through three(!) different methods, FaviconAstro ships typechecked config files in all of its starters and most Faviconprojects Anthony Fu has worked on have typechecked config files, Faviconhimself being a proponent of typing your config files

However, not every project has caught up yet. Have you ever tried writing by hand an ESLint or Prettier config only to realize that you don't know half of the settings (and their values) it can takes? Well, TypeScript can, and will, help you with that!

Let's see how we can use typed configs with some of the most popular JavaScript tools.

On .ts config files and helper methods

Unfortunately, most tools do not support just using a .ts extension or using an helper method, so we'll have to use JSDoc type annotations to achieve this

While this is unfortunate, luckily JSDoc annotations are just as easy to use.

ESLint

First install the FaviconDefinitelyTyped's type definition for FaviconESLint, @types/eslint using your favorite package manager. And then, in your eslintrc.js file, write the following

eslintrc.cjs
/** @type {import("@types/eslint").Linter.Config */
module.exports = {
// ... your eslint config here
};

And there you go, your ESLint config is now typechecked by TypeScript which also means that you now get suggestions and completions through your editor. It's fun AND interactive!

Let's do the same thing for Prettier.

Prettier

Similarly to ESLint, first install the types definition for FaviconPrettier through @types/prettier and then add the following to your .prettierrc.js

.prettierrc.cjs
/** @type {import("@types/prettier").Options */
module.exports = {
// ... your prettier config here
};

It's that easy and the benefits are very clear immediately. Frankly, in my opinion it's worth it for the completions alone, so convenient. Let's do more.

Tailwind

FaviconTailwind ships types directly and even support directly using TypeScript configs

tailwind.config.ts
import type { Config } from "tailwindcss";
export default {
// ... your tailwind config here
} satisfies Config;

Bonus: Astro

Astro ships with typechecked config files in all of its starters, and similar to Vite, also has a helper method to make it even easier to use

astro.config.ts
import { defineConfig } from "astro/config";
export default defineConfig({
// ...
});
Toggle mobile menu