带有打字稿的graphql - @FieldResolver 在compiled-to-js type-graphql 中不起作用

Posted

技术标签:

【中文标题】带有打字稿的graphql - @FieldResolver 在compiled-to-js type-graphql 中不起作用【英文标题】:graphql with typescript - @FieldResolver not working in compiled-to-js type-graphql 【发布时间】:2021-01-01 15:11:08 【问题描述】:

我是 type-graphql 的新手,我遇到了字段解析器无法正常工作的奇怪问题。

我正在使用一堆:

打字稿(3.9.5) type-graphql(1.0.0) typeorm(0.2.25) 阿波罗(2.16.0)。

每当我运行我的打字稿(使用 ts-node)时,一切正常,但是当我将编译后的 js 版本与 express 一起使用时,查询仅适用于简单的 db 字段,但 fieldResolvers 根本不起作用,最后我得到“不能为不可为空的字段返回 null”。 有趣的是,字段解析器是同一个 @Resolver 类中查询解析器的兄弟。查询被触发(放置控制台日志),但字段解析器从不这样做。有人知道吗?

以下是代码中的一些 sn-ps:

@Entity()
@ObjectType()
export class Member extends BaseEntity 
  @Field(() => ID)
  @PrimaryGeneratedColumn()
  id: string;

  @UseForSearch()
  @UseAsTitle()
  @Field(() => String)
  @IsEmail()
  @Column( type: 'varchar', unique: true )
  email: string;

  @Field(() => [Item])
  @OneToMany(type => Item, item => item.member)
  items?: Item[];

  @OneToMany(type => Review, review => review.member)
  reviews?: Review[];

  @Field(() => Number)
  itemsCount: number;


@Entity()
@ObjectType()
export class Item extends BaseEntity 
  @Field(() => ID)
  @PrimaryGeneratedColumn()
  id: string;

  @ManyToOne(type => Category, category => category.items)
  @JoinColumn( name: 'categoryId' )
  @Field(() => Category)
  category?: Category;

  @Field(() => String,  nullable: true )
  @Column(
    nullable: true,
  )
  name: string;

  @ManyToOne(type => Member, member => member.items)
  @JoinColumn( name: 'memberId' )
  @Field(() => Member)
  member?: Member;

  @Field(() => ID)
  @Column('int',  nullable: true )
  public memberId: number | null;

import  Resolver, Query, FieldResolver, Root, Ctx, Arg  from 'type-graphql';
import  getRepository, Repository  from 'typeorm';
import  Item  from '../entity';
import  Member  from '../entity/member';

@Resolver(of => Member)
export class MemberResolver 
  constructor(private itemsRepository: Repository<Item>) 
    this.itemsRepository = getRepository(Item);
  

  @Query(() => [Member])
  members() 
    console.log('in members query');
    return Member.find();
  

  @FieldResolver()
  async items(@Root() member: Member) 
    return await this.itemsRepository.find( where:  memberId: member.id  );
  

  @FieldResolver()
  async itemsCount(@Root() member: Member) 
    console.log('in itemsCount resolver');
    return this.itemsRepository.count( where:  memberId: member.id  );
  

query 
  members 
    email
    itemsCount
  


  "errors": [
    
      "message": "Cannot return null for non-nullable field Member.itemsCount.",
      "locations": [
        
          "line": 4,
          "column": 5
        
      ],
      "path": [
        "members",
        0,
        "itemsCount"
      ],
      "extensions": 
        "code": "INTERNAL_SERVER_ERROR",
        "exception": 
          "stacktrace": [
            "Error: Cannot return null for non-nullable field Member.itemsCount.",
            "    at completeValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:599:13)",
            "    at completeValueCatchingError (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:534:19)",
            "    at resolveField (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:465:10)",
            "    at executeFields (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:297:18)",
            "    at collectAndExecuteSubfields (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:752:10)",
            "    at completeObjectValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:742:10)",
            "    at completeValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:630:12)",
            "    at completeValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:596:21)",
            "    at completeValueCatchingError (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:534:19)",
            "    at /Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:655:25"
          ]
        
      
    
  ],
  "data": null

【问题讨论】:

【参考方案1】:

您的编译步骤(TS 到 JS)存在问题 - 如果它不发出 ES6 类和箭头函数,它会将 of =&gt; Member 视为具有原型的函数,因此它会认为它是对象类型类.

【讨论】:

【参考方案2】:

问题不在于编译。问题是你的数据

您看到的消息是Cannot return null for non-nullable field Member.itemsCount

好吧,要么在 itemsCount 中添加一个值,要么将该字段标记为可为空。问题是您在调用成员计数之前错过了等待

只需添加等待

 @FieldResolver()
  async itemsCount(@Root() member: Member) 
    console.log('in itemsCount resolver');
    return await this.itemsRepository.count( where:  memberId: member.id  );
  

【讨论】:

以上是关于带有打字稿的graphql - @FieldResolver 在compiled-to-js type-graphql 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有打字稿的角度材料设计

如何使用带有打字稿的“调试”模块

带有打字稿的 Angular 5 websocket 示例

带有打字稿的MongoDB聚合

在自定义输入元素上使用带有打字稿的 useRef

带有打字稿的嵌套角度指令