TypeGraphQL自定义类型做Arg参数报错,如何正确配置Field和Arg装饰器
问题原因和解决方案
错误根因分析
- 第一个报错:普通TS类型(比如你定义的
type Hits)仅存在于编译阶段,type-graphql无法通过反射系统将其映射为GraphQL可识别的类型,必须显式声明对应的GraphQL类型 - 第二个报错:
@ObjectType是用来定义接口返回值类型的装饰器,输入参数的自定义类型必须使用@InputType装饰器;同时你使用的GraphQLObjectType不适用于动态索引签名类型的映射,GraphQL原生不支持任意键的对象结构,需要用JSON标量来承接这类数据。 - 额外问题:即使你把
@ObjectType换成@InputType,hits字段的类型声明错误也会导致类型推断失败。
正确实现方案
场景1:Hits的字段结构固定
如果你的Hits结构是固定的(比如固定包含query、pageSize这类已知字段),优先用嵌套InputType实现,类型更安全:
import { InputType, Field, Resolver, Query, Arg } from 'type-graphql' // 先定义Hits的输入类型 @InputType() class HitsInput { @Field() name: string @Field() id: number // 其他固定字段按这个格式声明即可 } @InputType() class SearchListInput { @Field(() => HitsInput) hits: HitsInput } @Resolver() export default class SearchResolver { @Query(() => [String], { nullable: true }) async searchAssetList(@Arg('input', () => SearchListInput) input: SearchListInput) { return [] } }
场景2:Hits是动态键的任意结构
如果你确实需要Hits支持任意字符串键,使用GraphQLJSON标量承接:
- 先安装依赖:
npm install graphql-type-json @types/graphql-type-json
- 代码实现:
import { InputType, Field, Resolver, Query, Arg, UseMiddleware } from 'type-graphql' import GraphQLJSON from 'graphql-type-json' // 这里的Hits可以保留TS类型做编译阶段校验 type Hits = { [K: string]: string | number } @InputType() class SearchListInput { @Field(() => GraphQLJSON) hits: Hits } @Resolver() export default class SearchResolver { @Query(() => [String], { nullable: true }) // 显式在@Arg里声明输入类型,避免反射推断失败 async searchAssetList(@Arg('input', () => SearchListInput) input: SearchListInput) { // 这里input.hits会自动推导为Hits类型,也能正常拿到前端传入的动态数据 return [] } }
如果不需要封装input,直接传hits参数也可以:
@Resolver() export default class SearchResolver { @Query(() => [String], { nullable: true }) @UseMiddleware(isAuthenticated) async searchAssetList(@Arg('hits', () => GraphQLJSON) hits: Hits) { return [] } }
内容的提问来源于stack exchange,提问作者lutaev
相关产品推荐
相关产品推荐

