使用自定义类型的 TypeGraphql 字段和 Arg 装饰器

Posted

技术标签:

【中文标题】使用自定义类型的 TypeGraphql 字段和 Arg 装饰器【英文标题】:TypeGraphql Field and Arg decorators using custom type 【发布时间】:2021-12-11 05:48:12 【问题描述】:

我正在尝试使用 type-graphql 库构建解析器,但发现我无法定义自定义参数类型。这是我的代码:


type Hits =  [K: string]: string | number 

@Resolver()
export default class SearchResolver 
  @Query(() => [String],  nullable: true )
  @UseMiddleware(isAuthenticated)
  async searchAssetList(@Arg('hits') hits: Hits) 
    return [];
  

我遇到了一个错误:

NoExplicitTypeError: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for argument named 'hits' of 'searchAssetList' of 'SearchResolver' class.

我也尝试定义一个输入类:

type Hits =  [K: string]: string | number 

@ObjectType()
class SearchListInput 
  @Field(() => GraphQLObjectType)
  hits: Hits;


@Resolver()
export default class SearchResolver 
  @Query(() => [String],  nullable: true )
  async searchAssetList(@Arg('input') input: SearchListInput) 
    return []
  

又出现了一个错误:

UnhandledPromiseRejectionWarning: Error: Cannot determine GraphQL input type for argument named 'input' of 'searchAssetList' of 'SearchResolver' class. Is the value, that is used as its TS type or explicit type, decorated with a proper decorator or is it a proper input value?

@InputType 替换@ObjectType 也无济于事。如何正确定义@Field@Arg等装饰器?

感谢任何帮助。谢谢。

【问题讨论】:

【参考方案1】:

我认为您正在尝试使用带有数字和字符串的数组的 Arg,在这种情况下您应该这样做

@InputType()
class HitsInput

    @Field()
    Hits: [number | string];


@Resolver()
export default class SearchResolver 
  @Query(() => [String],  nullable: true )
  async searchAssetList(@Arg('input') input: HitsInput) 
    return []
  

如果不是这种情况,并且您想要一个带有动态字段的对象,则需要定义该对象,假设命中是否具有 Name 和 Id_Hits,

@InputType()
class HitsInput

    @Field()
    Id_Hits: number;

    @Field()
    Name: string;


@Resolver()
export default class SearchResolver 
  @Query(() => [String],  nullable: true )
  async searchAssetList(@Arg('input') input: HitsInput) 
    return []
  

如果你想在用户请求中有一个动态参数库,我不太确定这是否可行,但可以这样做

@InputType()
class HitsInput

    [key: string]: any;

【讨论】:

谢谢,路易斯,这是有道理的。我发现我无法将 typescript 类型或接口放入 @Field 装饰器中,我需要为它使用类 - 这就是原因。【参考方案2】:

几天前我遇到了完全相同的问题,我使用 GraphQLScalarType 通过创建自己的自定义类型来解决它 这里怎么做

import  GraphQLScalarType from "graphql";

export const GraphQLAny = new GraphQLScalarType(
    name: 'Any',
    serialize: (value) => value,
    parseValue: (value) => value,
    parseLiteral: (ast) => ast
);

在你的课堂上,你可以像这样使用你的 customTpe:

@ObjectType()
class SearchListInput 
  @Field(() => GraphQLAny)
  hits: typeof GraphQLAny;

【讨论】:

以上是关于使用自定义类型的 TypeGraphql 字段和 Arg 装饰器的主要内容,如果未能解决你的问题,请参考以下文章

输入对象类型`TypeName`必须定义一个或多个字段

TypeGraphql 和 Prisma 2 类型冲突

typeGraphql 如何更改字段验证的消息

有没有办法使用 TypeGraphQL 定义 GraphQL 片段?

没有插件的Joomla自定义类型/自定义字段?

在 drupal 8 的另一个自定义内容类型字段中使用自定义内容类型作为字段