When working on front-end typescript projects that integrate with GraphQL, you often find yourself handwriting types within your app. This is tedious and can lead to mistakes when typing your app.
Graphweaver will auto-generate a typescript file on each build that can be used in your project so that you no longer have to do this by hand.
By default, the file will be generated into the ./src/frontend
directory at the root of your project.
The types file is generated whenever you run one of the following commands:
graphweaver build
graphweaver start
graphweaver watch
It can be useful to also generate the file on its own. For that, you can use the command line:
graphweaver build-types
If you need to change the location of the types.ts file then you can use the fileAutoGenerationOptions
, like this:
export const graphweaver = new Graphweaver({
resolvers,
fileAutoGenerationOptions: {
typesOutputPath: ['./'],
},
});
In the example above, this will generate the typescript files in the root of the app.
typesOutputPath
can be either an array of strings or a single string. If you pass an array then the types file will be generated in each location.
Next, letβs look at how you might use this typescript file in your project. Let's say that you have an Album entity that is being returned from Graphweaver. The schema entity file looks like this:
import {
Field,
GraphQLEntity,
ID,
ObjectType,
RelationshipField,
SummaryField,
} from "@exogee/graphweaver";
import { Artist } from "../artist";
import { Track } from "../track";
import { Album as OrmAlbum } from "../../entities";
@ObjectType("Album")
export class Album extends GraphQLEntity<OrmAlbum> {
public dataEntity!: OrmAlbum;
@Field(() => ID)
id!: number;
@SummaryField()
@Field(() => String)
title!: string;
@RelationshipField<Album>(() => Artist, { id: (entity) => entity.artist?.id })
artist!: Artist;
@RelationshipField<Track>(() => [Track], { relatedField: "album" })
tracks!: Track[];
}
After running the builds command a types.ts
file is generated which includes a matching type:
export type Album = {
__typename?: 'Album';
artist?: Maybe<Artist>;
id: Scalars['ID']['output'];
title: Scalars['String']['output'];
tracks?: Maybe<Array<Track>>;
};
This can then be used in your front-end application to refer to this schema entity:
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import { Album } from "./types";
import "./App.css";
function App() {
const [count, setCount] = useState(0);
const album: Album = {
id: "1",
title: "The Dark Side of the Moon",
};
return (
<>
<div>
<p>
Title: { album.title }
</p>
</div>
</>
);
}
export default App;
In the example above, if someone were to remove the title attribute from the Album entity you would get a Typescript error in your app.