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

TypeGraphQL中createClient突变触发ArgumentValidationError问题排查

问题:TypeGraphQL创建客户突变时出现ArgumentValidationError错误

我用TypeGraphQL搭建了一个可查询项目及关联客户的简易API,调用createClient突变时收到ArgumentValidationError,提示an unknown value was passed to the validate function。直接传参数给突变没问题,但用解构输入对象的方式就触发错误,相关代码如下:

Client Schema

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

@ObjectType()
class ClientSchema {
    @Field(type => ID)
    id: string

    @Field()
    name: string

    @Field()
    email: string

    @Field()
    phone: string
}

export default ClientSchema

Client Resolver

import { Arg, Field, InputType, Mutation, Query, Resolver } from "type-graphql";

import exampleClients from "../utils/clients";
import ClientSchema from "../schemas/ClientsSchema";

@InputType()
class CreateClassInput {
    @Field()
    name: string

    @Field()
    email: string

    @Field()
    phone: string
}

@Resolver()
class ClientResolver {
  @Query((returns) => [ClientSchema])
  async clients() {
    return exampleClients;
  }

  @Query((returns) => ClientSchema)
  async client(@Arg("id") id: string) {
    const client = exampleClients.find((client) => client.id === id);

    if (!client) throw new Error("No such client"); 

    return client;
  }

  @Mutation((returns) => ClientSchema)
  async createClient(@Arg("data") createClassData: CreateClassInput) {
    const { name, email, phone } = createClassData;

    const newClient: ClientSchema = {
      id: String(exampleClients.length + 1),
      name,
      email,
      phone
    };

    exampleClients.push(newClient);

    return newClient;
  }
}

export default ClientResolver;

GraphQL Query

mutation createClient {
  createClient(data: { name: "Test Name", email: "Test Email", phone: "Test phone" }) {
    name
  }
}

问题原因与修复方案

核心错误

你把TypeGraphQL的@ObjectType()装饰的ClientSchema直接当成了普通TypeScript类型来断言newClient的类型。但@ObjectType()装饰器会给类添加额外的元数据属性,这些属性不属于业务数据,当验证器处理这个对象时,就会识别到未知值,抛出ArgumentValidationError。

修复步骤

  1. 定义独立的TS接口描述Client结构
    在ClientSchema文件里添加一个普通的TypeScript接口,用来描述客户数据的结构,和GraphQL的输出类型解耦:
import { ObjectType, Field, ID } from "type-graphql";

// 新增:普通TS接口,描述客户数据结构
export interface Client {
  id: string;
  name: string;
  email: string;
  phone: string;
}

@ObjectType()
class ClientSchema implements Client { // 让ObjectType实现这个接口
    @Field(type => ID)
    id: string

    @Field()
    name: string

    @Field()
    email: string

    @Field()
    phone: string
}

export default ClientSchema
  1. 修改newClient的类型断言
    在Resolver里,用新定义的Client接口来断言newClient的类型,而不是用ClientSchema:
// 先导入新增的Client接口
import ClientSchema, { Client } from "../schemas/ClientsSchema";

// ... 其他代码不变

@Mutation((returns) => ClientSchema)
async createClient(@Arg("data") createClassData: CreateClassInput) {
  const { name, email, phone } = createClassData;

  // 这里改用Client接口断言类型
  const newClient: Client = {
    id: String(exampleClients.length + 1),
    name,
    email,
    phone
  };

  exampleClients.push(newClient);
  return newClient;
}
  1. 可选优化:修正输入类型名称
    你的输入类型叫CreateClassInput,和业务(创建客户)不符,建议改成CreateClientInput,避免后续混淆:
@InputType()
class CreateClientInput { // 修改名称
    @Field()
    name: string

    @Field()
    email: string

    @Field()
    phone: string
}

// 同时修改突变的参数类型
async createClient(@Arg("data") createClientData: CreateClientInput) {
  // ... 代码不变
}

为什么直接传参数没问题?

直接传参数时,没有涉及到用ClientSchema作为类型断言的操作,不会引入装饰器添加的额外元数据,所以验证器不会检测到未知值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:50:23