You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apollo Server+TypeScript下解析器被迫指定关联值的问题

Apollo Server + TypeScript 类型生成的问题

我的GraphQL类型定义如下:

type User {
  id: ID!
  email: String!
  name: String!
  posts: [Post!]!
  reactions: [Reaction!]!
}

type Query {
  me: User
}

注:数组后的!是特意设置的,确保它们不会为null,最坏情况返回空数组。

我在根查询解析器中这样实现me:

me() {
  return {
    id: '123',
    name: 'Joe',
    email: 'joe@example.com',
  };
}

我省略了posts和reactions,打算交给user字段级解析器处理(已实现,这两个字段均返回[]),但这样会触发TypeScript类型校验失败——因为me()的类型要求返回完整的User对象,生成的类型定义如下:

// Code generated by Apollo Server
export type User = {
  __typename?: 'User';
  email: Scalars['String']['output'];
  id: Scalars['ID']['output'];
  name: Scalars['String']['output'];
  posts: Array<Post>;
  reactions: Array<Reaction>;
};

这里posts和reactions被标记为必填项。如果我在返回值中手动添加posts: [], reactions: [],类型校验就能通过。

疑问1:生成的类型是否不合理?

既然Apollo Server允许通过字段级解析器补全缺失的字段,生成的类型应该允许返回Partial<User>,而不是强制要求完整的User对象。

疑问2:为什么返回undefined/null能通过校验?

如果我这样写:

me() {
  return {
    id: '123',
    name: 'Joe',
    email: 'joe@example.com',
    posts: undefined,
    reactions: undefined,
  };
}

或者把undefined换成null,居然能通过TypeScript校验,但User类型明明声明这两个字段是必填且不能为null/undefined的。

实际场景的困扰

现在我只能用类型断言as User绕过校验,或者在返回数据库查询结果(比如Prisma查询)时,手动用.map给每个对象添加posts: undefined, reactions: undefined才能通过校验,但我看到的Apollo Server + Prisma集成示例里都没有这种额外操作。

我希望能直接这样写:

async me(_parent, _args, { db }) {
  return await db.user.findFirstOrThrow({ where: { email: 'joe@example.com' } });
}

而不需要额外处理缺失的字段。

我使用的是2023年11月19日的最新版NPM包。

内容的提问来源于stack exchange,提问作者Adeynack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:15:57