无法确定名为参数的 GraphQL 输入类型

Posted

技术标签:

【中文标题】无法确定名为参数的 GraphQL 输入类型【英文标题】:Cannot determine GraphQL input type for argument named 【发布时间】:2020-12-20 05:22:51 【问题描述】:

我有两个相关模型:

1.- 角色实体

import  Column, Entity, BaseEntity, OneToMany, PrimaryColumn  from "typeorm";
import  Field, ObjectType  from "type-graphql";

import  UserEntity  from "./user.entity";


@ObjectType()
@Entity(
    name: "tb_roles"
)
export class RoleEntity extends BaseEntity 

    @Field()
    @PrimaryColumn(
        name: "id",
        type: "character varying",
        length: 5
    )
    id!: string;

    @Field()
    @Column(
        name: "description",
        type: "character varying",
        nullable: true
    )
    description!: string

    @Field(() => [UserEntity])
    @OneToMany(() => UserEntity, user => user.role)
    users!: UserEntity[];

2.- 用户实体

import Field, ObjectType from "type-graphql";
import  BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn  from "typeorm";

import  RoleEntity  from "./role.entity";


@ObjectType()
@Entity(
    name: "tb_users"
)
export class UserEntity extends BaseEntity 
    @Field()
    @PrimaryGeneratedColumn("uuid", 
        name: "id"
    )
    id!: string;

    @Field()
    @Column(
        name: "username",
        type: "character varying",
        unique: true,
        nullable: false
    )
    username!: string;

    @Field()
    @Column(
        name: "last_name",
        type: "character varying",
        nullable: false
    )
    lastName!: string;

    @Field()
    @Column(
        name: "mother_last_name",
        type: "character varying",
        nullable: true
    )
    motherLastName!: string;

    @Field()
    @Column(
        name: "first_name",
        type: "character varying",
        nullable: false
    )
    firstName!: string;

    @Field()
    @Column(
        name: "middle_name",
        type: "character varying",
        nullable: true
    )
    middleName!: string;

    @Field()
    @Column(
        name: "email",
        type: "character varying",
        unique: true,
        nullable: false
    )
    email!: string;

    @Field()
    @Column(
        name: "password",
        type: "character varying",
        nullable: false
    )
    password!: string;

    @Field(() => RoleEntity)
    @ManyToOne(() => RoleEntity)
    @JoinColumn(name: "role_id")
    role!: RoleEntity;

    @Field()
    @Column(
        name: "is_active",
        type: "character varying",
        nullable: true
    )
    isActive!: boolean;

    @Field()
    @CreateDateColumn(
        name: "created_at"
    )
    createdAt!: string;

    @Field()
    @UpdateDateColumn(
        name: "updated_at"
    )
    updatedAt!: string;

这是用户的解析器:

import Arg, Mutation, Query, Resolver from "type-graphql";
import bcrypt from "bcryptjs";

import UserEntity from "../../entity/user.entity";
import RoleEntity from "../../entity/role.entity";


@Resolver()
export class UserResolver 
    @Query(() => [UserEntity])
    async users() 
        return await UserEntity.find();
    

    @Mutation(() => UserEntity)
    async createUser(
        @Arg('username') username: string,
        @Arg('lastName') lastName: string,
        @Arg('motherLastName') motherLastName: string,
        @Arg('firstName') firstName: string,
        @Arg('middleName') middleName: string,
        @Arg('email') email: string,
        @Arg('password') password: string,
        @Arg('role') role: RoleEntity,
        @Arg('isActive') isActive: boolean
    ): Promise<UserEntity> 

        const hashedPassword = await bcrypt.hashSync(password, bcrypt.genSaltSync(10));

        const user = UserEntity.create(
            username,
            lastName,
            motherLastName,
            firstName,
            middleName,
            email,
            password: hashedPassword,
            role,
            isActive
        ).save();

        return user;
    

但是,我得到了这个错误:

(节点:14788)UnhandledPromiseRejectionWarning:错误:无法确定“UserResolver”类的“createUser”的名为“role”的参数的 GraphQL 输入类型。是否 用作其 TS 类型或显式类型的值是用适当的装饰器装饰的还是适当的输入值?

我需要你的帮助。

【问题讨论】:

可能相关:github.com/MichalLytek/type-graphql/issues/371 【参考方案1】:

我解决了我的问题,我修改了我的两个模型,在 UserEntity 中我删除了:

@Field(() => RoleEntity)
    @ManyToOne(() => RoleEntity)
    @JoinColumn(name: "role_id")
    role!: RoleEntity;

我加了

@Field()
@Column(name: 'role_id')
roleId!: string;

@Field(() => RoleEntity)
role!: RoleEntity;
@ManyToOne(() => RoleEntity, role => role.userConnection)
@JoinColumn(name: 'role_id')
roleConnection!: Promise<RoleEntity>

在 RoleEntity 中,我添加了:

@OneToMany(() => UserEntity, user => user.roleConnection)
userConnection!: Promise<UserEntity[]>

但是,我不知道我是否以正确的方式进行测试(游乐场):

query users 
  users 
    firstName
    username
    roleId
    role 
      description
    
  

部分错误是:

"message": "不能为不可为空的字段 UserEntity.role 返回 null。",

有人可以向我解释一下,错误是什么或在哪里?

谢谢。

【讨论】:

【参考方案2】:

我修复了在 userResolver 中添加这个:

@FieldResolver()
    async role(@Root() user: UserEntity): Promise<RoleEntity | undefined> 
        //const role: RoleEntity | undefined = await RoleEntity.findOne(user.roleId);
        //return role;
        return await RoleEntity.findOne(user.roleId);
    

谢谢。

【讨论】:

【参考方案3】:

错误是因为您不能在突变中使用 ObjectType 参数¹,只能使用普通标量类型或 InputType:https://typegraphql.com/docs/resolvers.html#input-types

¹:在您的情况下为 RoleEntity ObjectType。

【讨论】:

以上是关于无法确定名为参数的 GraphQL 输入类型的主要内容,如果未能解决你的问题,请参考以下文章

错误:使用 Nestjs + Graphql + Typeorm 时无法确定 GraphQL 输入类型

NestJS 中与 GraphQL 的 Prisma 自关系

嵌套错误:无法确定 getProducts 的 GraphQL 输出类型

Type-graphql with lerna --- 错误:无法确定 id 的 GraphQL 输出类型

GraphQl 将查询参数传递给子类型

TypeError:无法读取未定义的属性“类型”