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

TypeGraphQL中如何让User查询委托字段给字段解析器?

问题描述

我想创建一个User查询,把字段委托给下方的字段解析器,请问查询里应该返回什么内容才能实现这个行为?

代码示例:

@ObjectType()
class User {
  @Field((_type) => ID)
  id!: string;

  @Field((_type) => [View])
  saved!: View[];
}


@Resolver(of => User)
export class UserResolver {
  @Authorized()
  @Query((_returns) => User, { nullable: false })
  async user(@Ctx() { prisma, uid }: context.AuthorizedContext) {
    return {
      id: uid,
    };
  }

  @FieldResolver()
  async saved(
    @Root() { id }: User,
    @Ctx() { prisma }: context.AuthorizedContext
  ) {
    console.log("HELLO")

    const savedViews = await prisma.saved.findMany({
      where: { userId: id },
      include: { View: true },
    });

    return savedViews.map((dboView) => dboView.View);
  }
}

我尝试不返回saved字段时,出现错误:Cannot return null for non-nullable field User.saved

解决方法

你遇到的问题是因为User类里saved字段被定义为非空数组,但查询返回的对象里没有这个字段时,GraphQL会默认将其视为null,触发非空约束错误。要实现字段委托给FieldResolver,可以用以下两种方式:

方式一:用类型断言绕过TypeScript类型检查

修改查询方法的返回值,用类型断言明确告诉TypeScript只需要返回id字段,剩余字段交给字段解析器处理:

async user(@Ctx() { prisma, uid }: context.AuthorizedContext) {
  return { id: uid } as Pick<User, 'id'>;
}

这样既满足TypeScript的类型要求,又不会让GraphQL认为saved字段是null,字段解析器会正常接管该字段的逻辑。

方式二:返回空数组作为占位符

在查询返回的对象里给saved字段设置空数组占位符,既符合TypeScript的必填字段要求,也不会触发GraphQL的非空错误,最终字段解析器会覆盖这个占位值:

async user(@Ctx() { prisma, uid }: context.AuthorizedContext) {
  return {
    id: uid,
    saved: []
  };
}

两种方式都能让FieldResolver正常执行(控制台会打印"HELLO"),最终返回正确的saved数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:55:23