When I was learning web development I built this site with Gatsby using the Gatsby-starter-hello-world template without using Typescript. Typescript was on my things-to-learn bucket list but never got to it until I started working professionaly. After learning Typescript I cannot imagine building anything without it!
In case you don't know the benefits of Typescript, here's a list to why you should start using it:
- Early Error Detection: TypeScript's static type checking can catch errors early in the development process, reducing the likelihood of runtime issues.
- Improved Code Quality: With TypeScript, you get better tooling support, allowing for more reliable refactoring and improved code readability.
- Enhanced Code Navigation: TypeScript's type annotations provide rich information for code navigation and auto-completion in your IDE.
- Type-Safe GraphQL Queries: If you use GraphQL for fetching data TypeScript allows you to have type-safety for your GraphQL results, reducing the chance of data-related bugs.
- Better Collaboration: The added type information makes it easier for team members to understand code written by others.
Here's how to migrate a Gatsby site to Typescript.
Step 1: Clean Up
Before integrating typescript, clean your cache:
Step 2: Convert Files to TypeScript
The first step in the conversion process is to rename your existing .js
and .jsx
files to .ts
and .tsx
, respectively. This tells Gatsby that these files are now written in TypeScript.
Step 3: Install Dependencies
Next, we need to install the required TypeScript and type declaration dependencies. In your project directory, run the following command:
npm install --save-dev @types/node @types/react @types/react-dom typescript
Step 4: Create tsconfig.json
A tsconfig.json
file is essential for configuring TypeScript in your project. You can generate one using the TypeScript compiler by running:
Alternatively, you can use the tsconfig.json file from the official Gatsby minimal starter TypeScript repository:
You might find yourself editing some of the tsconfig.json
properties to reflect the setup/configs of your project.
Step 5: Rename Gatsby Files
Rename these Gatsby filenames to match the new file extensions. Rename the following files accordingly:
gatsby-node.js
to gatsby-node.ts
gatsby-config.js
to gatsby-config.ts
gatsby-browser.js
to gatsby-browser.tsx
gatsby-ssr.js
to gatsby-ssr.tsx
Step 6: Replace require.resolve with path.resolve
TypeScript does not support require.resolve
, so you'll need to replace these instances with path.resolve
calls. Here's an example of how to do this in a gatsby-node.ts
file:
import path from "path";
const template = path.resolve(`./src/templates/template.tsx`);
Note the file extension in ./src/templates/template.tsx
. You will need to change all .js
and .jsx
extensions in gatsby.node
to .tsx
or gatsby develop
will throw an error.
Step 7: Handling Hot-reloading
Be aware that when changing the siteMetadata
in gatsby-config
, hot-reloading won't occur during development. A restart of the development server will be necessary in this case.
Step 8: GraphQL Typegen
To have type-safety for your GraphQL results and autocompletion in your IDE, you can use Gatsby's GraphQL Typegen feature. Set the graphqlTypegen
option to true
in your gatsby-config.ts
file:
module.exports = {
graphqlTypegen: true,
};
Make sure your tsconfig.json includes "include": ["./src/**/*"]
.
Step 9: Working with GraphQL Queries
When using TypeScript with GraphQL queries, ensure that your query has a name:
export const query = graphql`
query blogsPage {
}
`;
In order to get the graphQL query types you will need to restart your development server so Gatsby picks it up.
Now, you can access the query type using the global namespace Queries
:
import { PageProps } from "gatsby"
const Blogs = ({ data }: PageProps<Queries.blogsPageQuery>) => {
};
Step 10: Dealing with Read-only Types
When using data from GraphQL queries in your state, you might encounter read-only types that don't allow mutability. To address this, explicitly cast the data to the desired type, like this:
import { PageProps } from "gatsby"
const Blogs = ({ data }: PageProps<Queries.blogsPageQuery>) => {
const [blogs, setBlogs] = useState<Queries.ContentfulBlog[]>(data.allContentfulBlog.nodes as Queries.ContentfulBlog[]);
.
.
.
setBlogs(data.allContentfulBlog.nodes as Queries.ContentfulBlog[]);
.
.
.
}
By doing this, TypeScript won't complain about mutability issues.
TypeScript may complain about potentially undefined values in your code. Use optional chaining .?
to handle such cases gracefully. If you are converting a larger, existing codebase to TypeScript, consider doing it in manageable steps. Focus on critical components and gradually migrate other parts of the project.
And this is how to convert a Gatsby site to using Typescript.