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

如何在TypeGraphQL中省略字段?场景示例与实现疑问

解决方案

针对你的需求,最合理的实现方式有两种,推荐优先选择拆分查询的方案,API更清晰且符合GraphQL最佳实践:


方案一:拆分两个独立查询(推荐)

分别定义「获取当前用户信息」和「搜索公开用户信息」两个查询,对应不同的返回类型,从根源上区分敏感字段的访问权限:

1. 定义类型

先定义公开用户类型(不含敏感字段),再让完整用户类型继承它:

import { ObjectType, Field, ID } from "type-graphql";

@ObjectType()
class PublicUser {
  @Field(() => ID)
  id: string;

  @Field()
  username: string;
}

@ObjectType()
class User extends PublicUser {
  @Field({ nullable: true })
  email: string; // 仅当前用户能看到的敏感字段
}

2. 实现Resolver

import { Query, Authorized, Arg, Ctx } from "type-graphql";
import { UserModel } from "./your-user-model-path";
import { Context } from "./your-context-type"; // 假设Context包含currentUser

export default class UserResolver {
  // 获取当前用户自己的完整信息(含邮箱)
  @Authorized() // 仅登录用户可访问
  @Query(() => User)
  async me(@Ctx() { currentUser }: Context) {
    return await UserModel.findById(currentUser.id);
  }

  // 搜索其他用户的公开信息(不含邮箱)
  @Query(() => PublicUser)
  async user(@Arg('username') username: string) {
    const user = await UserModel.findOne({ username });
    if (!user) throw new Error("用户不存在");
    return user;
  }
}

方案二:单查询结合字段级权限控制

如果一定要用同一个查询实现,可通过字段级的自定义权限校验,判断当前登录用户是否为被查询的用户,从而控制敏感字段是否返回:

1. 配置权限检查器

确保TypeGraphQL的权限检查器能从上下文获取当前用户:

import { buildSchema } from "type-graphql";
import { UserResolver } from "./your-resolver-path";

const schema = await buildSchema({
  resolvers: [UserResolver],
  authChecker: ({ context }) => {
    // 假设context.currentUser是从请求头token解析出的当前登录用户
    return !!context.currentUser;
  },
});

2. 修改User类型的字段权限

给email字段添加自定义权限逻辑,只有当被查询用户ID和当前用户ID一致时才返回:

import { ObjectType, Field, ID, Authorized } from "type-graphql";
import { Context } from "./your-context-type";

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

  @Authorized({
    custom: ({ root, context }: { root: User; context: Context }) => {
      // root是当前要返回的用户对象,context.currentUser是登录用户
      return root.id === context.currentUser?.id;
    },
  })
  @Field({ nullable: true })
  email: string;

  @Field()
  username: string;
}

3. 实现Resolver

去掉查询方法上的@Authorized("CURRENT_USER"),允许所有用户调用,由字段级权限控制敏感字段:

import { Query, Arg, Ctx } from "type-graphql";
import { UserModel } from "./your-user-model-path";
import { Context } from "./your-context-type";

export default class UserResolver {
  @Query(() => User)
  async user(
    @Arg('username') username: string,
    @Ctx() context: Context
  ) {
    const user = await UserModel.findOne({ username });
    if (!user) throw new Error("用户不存在");
    return user;
  }
}

为什么不推荐你原来的手动解析字段方案?

手动处理字段会增加代码维护成本,且容易遗漏场景。TypeGraphQL的类型系统和权限装饰器已经帮我们封装了这类逻辑,直接利用框架特性更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:15:44