Gatsby typescript migration


I spent this weekend to migrate this blog from es6 to typescript:

git show --stat
... ...
 48 files changed, 5934 insertions(+), 3149 deletions(-)

The massive changeset covers 99% type-related linting errors. Here is my take-away.


I followed the Migrating to TypeScript guide to convert the .js/.jsx to .ts/.tsx, and added the tsconfig.json to scaffold the typescript project.

Add typescript to eslint integration:

yarn add --dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint typescript

Then I expanded the eslintConfig section in the package.json to integrate the typescript typecheck to eslint.

  "eslintConfig": {
    "extends": [
    "plugins": [
    "root": true,
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
      "project": [
      "tsconfigRootDir": "./"

Suddenly, I had thousands of linting errors due to the lack of type annotations.

Type annotation

We could use pre-defined types provided by gatsby, such as in gatsby-ssr.tsx:

export const onRenderBody: GatsbySSR['onRenderBody']

We could also leverage the graphql codegen to reduce the boilerplate code. Add graphqlTypegen: true in the gatsby-config.ts, then rerun gatsby develop. it will spit gatsby-types.d.ts with types generated from graphql query and fragments. We can add the type inferences in the package.json:

  "types": "src/gatsby-types.d.ts",

This setup will enable the Queries namespace type as the following:

export default function Page({ data }: PageProps<Queries.PageByURIQuery>) {
  // Render a single page, such as /about.
  ... ...


I also adopted the Gatsby Head API, and deprecated the react-helm library to tweak the title HTML head.