Open2

【GraphQL】Nexusでresolveの引数に型がつかない

airRnotairRnot

GraphQLに入門して、Nexusを触っていたところ、以下の問題に直面。

import { objectType, extendType } from 'nexus';

export const Post = objectType({
  name: 'Post', // <- Name of your type
  definition(t) {
    t.int('id'); // <- Field named `id` of type `Int`
    t.string('title'); // <- Field named `title` of type `String`
    t.string('body'); // <- Field named `body` of type `String`
    t.boolean('published'); // <- Field named `published` of type `Boolean`
  },
});

export const PostQuery = extendType({
  type: 'Query',
  definition(t) {
    t.nonNull.list.field('drafts', {
      type: 'Post',
      resolve(_parent/*: any */, _args/*: any */, ctx/*: any */) {
        return [{ id: 1, title: 'Nexus', body: '...', published: false }];
      },
    });
  },
});

「あれ、ctxとか全部anyになってる!?」

はい、resolveの引数に型が反映されていなくて詰まってしまいました。

私はPrismaと連携させたかったのでcontextは以下のように設定していました。

context.ts
import type { PrismaClient } from '@prisma/client';

import { prisma } from '@/libs/prisma';

export interface Context {
  prisma: PrismaClient;
}

export function createContext(): Context {
  return {
    prisma,
  };
}

schema.ts
import { join } from 'path';

import { makeSchema } from 'nexus';

import * as types from '@/graphql/types';

export const schema = makeSchema({
  types,
  outputs: {
    typegen: join(
      process.cwd(),
      'node_modules',
      '@types',
      'nexus-typegen',
      'index.d.ts'
    ),
    schema: join(process.cwd(), 'src', 'graphql', 'schema.graphql'),
  },
  contextType: {
    export: 'Context',
    module: join(process.cwd(), 'src', 'graphql', 'context.ts'),
  },
});

どうやら、node_modules/@types/nexus-typegen/index.d.tsが読み込まれていなかったのが原因でした。なので、tsconfig.jsonを修正すれば解決です。

tsconfig.json
{
  "extends": "@tsconfig/strictest/tsconfig.json",
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "lib": ["esnext"],
    "outDir": "dist",
    "noPropertyAccessFromIndexSignature": false,
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"],
      "~/*": ["./*"]
    },
    "esModuleInterop": true,
    "isolatedModules": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "types": ["@types/jest", "@types/nexus-typegen", "@quramy/jest-prisma-node"] // @types/nexus-typegenを追加
  },
  "include": ["src/**/*", "__tests__/**/*", "scripts/**/*"],
  "exclude": ["node_modules", "dist", "scripts", "**/generated", "**/fabbrica"]
}

airRnotairRnot

おまけ

Nexus + Prismaでrelationsの部分がうまく取得できない事例が発生してたけど、prisma v5.0.0を入れていたせいだった。prisma v4に落としたら無事成功。