GraphQL YogaのResolverに型をつけたい
GraphQL Yoga を使って個人開発をしています。
その中で記述した typeDefs に対して、resolver の型が保証されてほしかったのでやってみました。
困っていること
GraphQL yoga では以下のように schema を作成します。(コード例は 公式ドキュメントからコピペです)
import { createSchema } from "graphql-yoga";
export const schema = createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String
}
`,
resolvers: {
Query: {
hello: () => "world",
},
},
});
ここで例えば hello
の型を Int
にしても、TypeScript の型上はエラーにはなりません。
// 略
typeDefs: /* GraphQL */ `
type Query {
hello: Int # Int型に変更
}
`,
resolvers: {
Query: {
hello: () => "world", // 型エラーにならない
},
// 略
しかし、GraphQL の型では hello
の resolver は Int
型の値を返すことを期待しているため、実行時エラーが発生します。
ERR Error: Int cannot represent non-integer value: "world"
typeDefs の型を変更したら、TypeScript の型上でエラーが出るようにしていきます。
やったこと
Resolver に型をつけるためには、記述した TypeDefs から Resolver に期待する型を generate する必要があります。
この生成に graphql-code-generator を利用します。
また、TypeScript の Resolver の型を生成したいため、一緒に必要な Plugin も install します。
npm i -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers
install が完了後、下記コマンドで graphql-codegen の初期化と config の設定をします。(対話式で設定が始まります)
npx graphql-codegen init
初期化が完了したら、GraphQL Server を立ち上げた状態でコマンドを実行すると型が生成されます。
npm run codegen
これで指定した生成先の ts ファイルに Resolver の型が生成されるので、import して型を当てます。
import { createSchema } from "graphql-yoga";
import { Resolvers } from "../generated/graphql";
const resolvers: Resolvers = {
Query: {
hello: () => "world",
},
};
export const schema = createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String
}
`,
resolvers,
});
これで記述した typeDefs
に対して resolver の型が保証されます。
試しに先程と同様に typeDefs を変更後、generate のコマンドを走らせると、
type Query {
hello: Int # Int型に変更
}
しっかりと TypeScript Compiler が怒ってくれます。
これで typeDefs に対して正しい型が付けられた Resovler で開発ができるようになりました。
Discussion