Generate types with GraphQL Codegen
Faust.js provides built-in TypeScript support, including types for Templates, Blocks, and more. This guide will show you how to generate fully typed definitions for your custom GraphQL queries and fragments using GraphQL Code Generator.
If you're looking to generate Apollo-specific fragment matching metadata (i.e. possibleTypes
), see the faust generatePossibleTypes
command. However, that command does not produce TypeScript definitions for your queries. For typing your queries in Faust, continue reading below.
0. Prerequisites
If you haven't already, follow the Basic Setup steps to get Faust.js configured. Once your project is set up, add @graphql-codegen/cli
to your project:
npm install -D typescript @graphql-codegen/cli
1. Add Codegen Configuration
In the root of your project, create a configuration file named codegen.ts
import { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
schema: "https://faustexample.wpengine.com/graphql",
documents: ["src/**/*.{tsx,ts}"],
generates: {
"./src/__generated__/": {
preset: "client",
plugins: [],
presetConfig: {
gqlTagName: "gql",
},
},
},
ignoreNoDocuments: true,
};
export default config;
2. Add Codegen Script
Next, update your package.json to add a script for running the code generator:
{
"scripts": {
"generate:types": "graphql-codegen"
}
}
Now you can run:
npm run generate:types
This command will scan your src/
folder for any GraphQL queries or fragments, then generate TypeScript types in src/__generated__/graphql.ts
.
Be sure to enable WPGraphQL introspection before running the npm run generate
command since it is disabled by default.
3. Using Generated Types
A. Typing Templates
After Codegen runs, you'll see auto-generated types in graphql.ts. For example:
export type GetPostQueryVariables = Exact<{
databaseId: Scalars["ID"];
asPreview?: InputMaybe<Scalars["Boolean"]>;
}>;
export type GetPostQuery = {
// ...
};
You can use these types with the FaustTemplate
helper in your WordPress templates:
import { gql } from "../__generated__";
import { GetPostQuery } from "../__generated__/graphql";
import { FaustTemplate } from "@faustwp/core";
const Component: FaustTemplate<GetPostQuery> = (props) => {
// `props.data` and other fields are now typed!
return <div>{props?.data?.post?.title}</div>;
};
export const pageQuery = gql(/* GraphQL */ `
query GetPost($databaseId: ID!, $asPreview: Boolean) {
...
}
`);
Then you can inspect all the types in the props
parameters as you type:
All the data from the query results will be properly typed based on the introspected schema:
B. Typing Block Components
If you create blocks with @faustwp/blocks
, you can use the WordPressBlock type to add strong typing to those components:
import { gql } from "../__generated__";
import { WordPressBlock } from "@faustwp/blocks";
import { CoreParagraphFragmentFragment } from "../__generated__/graphql";
const CoreParagraph: WordPressBlock<CoreParagraphFragmentFragment> = (
props,
) => {
return <p>{props.attributes?.content}</p>;
};
export const fragments = {
entry: gql(`
fragment CoreParagraphFragment on CoreParagraph {
attributes {
content
}
}
`),
key: "CoreParagraphFragment",
};
By passing in CoreParagraphFragmentFragment
to WordPressBlock, TypeScript enforces that props only contains fields you've declared in the GraphQL fragment.