不能对 Type-GraphQL 字段类型使用类型“对象”

Posted

技术标签:

【中文标题】不能对 Type-GraphQL 字段类型使用类型“对象”【英文标题】:can't use type 'object' for Type-GraphQL field types 【发布时间】:2020-05-29 00:31:24 【问题描述】:

我想为我的 NestJs API 创建一个 GraphQL 层。所以基于这个接口持有一个键/值对

export interface Mapping 
  id: string;
  value: object;

我创建了一个 DTO 作为 GraphQL 查询的返回类型

@ObjectType()
export class MappingDTO 
  @Field(() => ID)
  id: string;

  @Field()
  value: object;

所以当我想找到所有映射时,我会想出这个

  @Query(() => [MappingDTO])
  public async mappings(): Promise<Mapping[]> 
    return this.mappingsService.getMappings();
  

很遗憾,我不能将object 用于值字段。我收到此错误

NoExplicitTypeError:您需要为 MappingDTO#value !

当改变类型时,例如到string 启动时不会抛出任何错误。问题是我无法指定显式类型,因为我的 MongoDB 存储了持有“任何东西”的对象。

如何修复我的解析器或 DTO 以处理对象类型?


编辑:

解析器装饰器也是如此。当我有这个

  @Query(() => Object)
  public async getValueByKey(@Args('id') id: string): Promise<object> 
    return this.mappingsService.getValueByKey(id);
  

我收到此错误

错误:无法确定 getValueByKey 的 GraphQL 输出类型

【问题讨论】:

【参考方案1】:

听起来您应该使用自定义 JSON 标量。喜欢this one。

import  GraphQLJSONObject  from 'graphql-type-json'

这可以直接在字段装饰器中使用:

@Field(() => GraphQLJSONObject)
value: object

或者您可以将装饰器保留为@Field(),并将适当的scalarsMap 添加到您传递给buildSchema 的选项中。更多详情请参阅the docs。

【讨论】:

祝福你@daniel-rearden ! 文档链接需要更新。这是正确的链接。 typegraphql.com/docs/scalars.html#custom-scalars【参考方案2】:

只是指出 GraphQL 的整个想法是声明式数据获取。 您也可以在 GraphQL 中定义自定义类型,标量类型没有对象作为选项,但您可以像这样定义自己的类型。

type customObject 
      keyOne: Int!
      KeyTwo: String!
      ...
      key(n): ...

并在接口、查询、突变中使用此类型:

export interface Mapping 
      id: string;
      value: customObject;

您可能认为您必须在这种类型的 customObject 中定义您存储在 mongoDB 中的对象的每个键,但您不必这样做。这就是 GraphQL 声明式数据获取的用武之地。您只需在要在前端使用的类型 (customObject) 中定义那些字段,不需要从 DB 中获取完整的对象。

【讨论】:

以上是关于不能对 Type-GraphQL 字段类型使用类型“对象”的主要内容,如果未能解决你的问题,请参考以下文章

Type-GraphQL 上 JSON 字段的类型

如何使用 type-graphql 定义对象类型

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

Type-GraphQL 的参数错误 - 没有参数类型?

错误:只能有一种名为“Upload”的类型 - Apollo、Express、Type-Graphql

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