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

TypeScript类型与GraphQL类型冲突的解决方法

GraphQL解析器TypeScript类型不兼容错误解决

问题背景

现有如下GraphQL解析器代码:

import { Resolvers } from "../../generated/schema";

export const resolvers: Resolvers = {
  Query: {
    getS: async (_parent: unknown, { id }: { id: string }): Promise<GenericResponse<S>> => { ... }
  }
}

对应的GraphQL Schema:

type Query {
  getS(id: ID!): getSResponse
}

type S {
  id: ID!,
  wac: Float!,
  beginDate: String!,
  endDate: String!,
}

type getSResponse implements GenericResponse {
  status: Status!
  data: S!
}

通过GraphQL Codegen生成的类型定义:

export type Resolvers<ContextType = any> = {
  Query?: QueryResolvers<ContextType>;
}

export type QueryResolvers<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
getS?: Resolver<Maybe<ResolversTypes['getSResponse']>, ParentType, ContextType, RequireFields<QueryGetSArgs, 'id'>>;
}

export type QueryGetSArgs = {
  id: Scalars['ID']['input'];
};

export type Scalars = {
  ID: { input: string | number; output: string; }
  String: { input: string; output: string; }
  Boolean: { input: boolean; output: boolean; }
  Int: { input: number; output: number; }
  Float: { input: number; output: number; }
};

出现的TypeScript错误:

Type '(_parent: unknown, { id }: myType) => Promise<GenericResponse<S>>' is not assignable to type 'Resolver<Maybe<ResolverTypeWrapper<GetWacPercentageResponse>>, {}, any, RequireFields<QueryGetSArgs, "id">> | undefined'.
  Type '(_parent: unknown, { id }: myType) => Promise<GenericResponse<S>>' is not assignable to type 'ResolverFn<Maybe<ResolverTypeWrapper<GetSResponse>>, {}, any, RequireFields<QueryGetSArgs, "id">>'.
    Types of parameters '__1' and 'args' are incompatible.
      Type 'RequireFields<QueryGetSArgs, "id">' is not assignable to type 'myType'.
        Types of property 'id' are incompatible.
          Type 'NonNullable<string | number>' is not assignable to type 'string'.
            Type 'number' is not assignable to type 'string'.ts(2322)

错误原因

GraphQL的ID标量类型在输入时允许string | number类型,但解析器里硬把id的类型定义为string,导致与Codegen生成的NonNullable<string | number>类型不匹配,触发类型错误。

解决方案

方案1:使用Codegen生成的参数类型

直接复用生成的QueryGetSArgs作为解析器的参数类型,无需手动定义:

import { Resolvers, QueryGetSArgs } from "../../generated/schema";

export const resolvers: Resolvers = {
  Query: {
    getS: async (_parent: unknown, { id }: QueryGetSArgs): Promise<GenericResponse<S>> => {
      // 若业务要求id必须为字符串,可在此处做类型转换或校验
      const stringId = String(id);
      // 后续使用stringId处理业务逻辑
      ...
    }
  }
}

方案2:修改Codegen配置限制ID输入类型

如果业务场景中ID永远是字符串,可在Codegen配置文件(如codegen.ts)中自定义ID标量的输入类型:

import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  // 其他配置项...
  config: {
    scalars: {
      ID: 'string'
    }
  }
};

export default config;

重新生成类型定义后,QueryGetSArgs中的id类型会变为string,与解析器中的定义匹配。

方案3:在解析器中处理类型兼容

若无法修改Codegen配置,可通过类型转换或断言兼容两种类型:

export const resolvers: Resolvers = {
  Query: {
    getS: async (_parent: unknown, { id }: { id: string | number }): Promise<GenericResponse<S>> => {
      // 转换为字符串(推荐,避免类型断言的风险)
      const strId = String(id);
      // 或使用类型断言(需确保业务逻辑能接受数字转字符串后的结果)
      // const strId = id as string;
      ...
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:35:43