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
相关产品推荐
相关产品推荐

