复用CatBase时CatInputType报错:必须定义至少一个字段
嘿,这个问题我之前也踩过坑!其实核心原因是TypeGraphQL的装饰器元数据继承规则和你想的不一样~
问题根源
你写的CatBase类只是一个普通的TypeScript类,没有添加任何TypeGraphQL的装饰器标记。而TypeGraphQL的@ObjectType()和@InputType()装饰器是通过类的元数据来识别字段的,普通基类的@Field()装饰器不会自动被子类继承识别——所以当CatInputType继承CatBase时,TypeGraphQL根本看不到基类里的字段,就会抛出"Input Object type CatInputType must define one or more fields"的错误。
而你直接在CatInputType里声明字段时,@Field()装饰器是直接挂在CatInputType类上的,TypeGraphQL能直接读取到这些元数据,所以就正常工作了。
两种可行的解决方案
方案1:给基类标记抽象的TypeGraphQL装饰器
TypeGraphQL允许给基类添加@ObjectType({ isAbstract: true })和@InputType({ isAbstract: true })装饰器,标记为抽象类后,子类就能继承基类的字段元数据了。修改后的代码如下:
import { Document } from 'mongoose'; import { ObjectType, InputType, Field, ID } from 'type-graphql'; export interface Cat extends Document { readonly name: string; readonly age?: number; } // 给基类添加抽象的ObjectType和InputType装饰器 @ObjectType({ isAbstract: true }) @InputType({ isAbstract: true }) class CatBase { @Field() name: string; @Field({ nullable: true }) age?: number; } @ObjectType() export class CatObjectType extends CatBase implements Cat { @Field(type => ID) id: string; } @InputType() export class CatInputType extends CatBase implements Cat { }
方案2:使用TypeGraphQL的工具类生成InputType
如果你不想用基类继承,也可以用TypeGraphQL提供的PickType/OmitType工具类,从已有的ObjectType中挑选或排除字段来生成InputType,这样更灵活:
import { Document } from 'mongoose'; import { ObjectType, InputType, Field, ID, PickType } from 'type-graphql'; export interface Cat extends Document { readonly name: string; readonly age?: number; } @ObjectType() export class CatObjectType implements Cat { @Field(type => ID) id: string; @Field() name: string; @Field({ nullable: true }) age?: number; } // 从CatObjectType中挑选name和age字段生成InputType @InputType() export class CatInputType extends PickType(CatObjectType, ['name', 'age'] as const) { }
两种方案都能解决你的问题,你可以根据自己的代码结构选择合适的方式~
内容的提问来源于stack exchange,提问作者Pavel Perevezencev

