NestJS+GraphQL报错:无法确定author字段的GraphQL输入类型
问题分析
报错原因很明确:GraphQL的InputType和ObjectType是完全独立的类型体系,不能在InputType类中直接使用ObjectType类作为字段类型。
你复用了PostBaseDTO同时生成ObjectType(PostDTO)和InputType(CreatePostInputDTO),但其中的author字段引用的是ObjectType的UserDTO,导致InputType工厂无法识别该类型,从而抛出错误。
另外你之前尝试添加的UserDTOInput没有解决问题,核心原因是PostBaseDTO本身是ObjectType,通过IntersectionType转换为InputType时,内部的author字段类型并没有自动切换为InputType版本。
解决方案
步骤1:完善User的InputType定义
在user.dto.ts中,为User创建独立的InputType基础类和完整InputDTO:
import { Field, InputType, IntersectionType, ObjectType, OmitType, PartialType, } from '@nestjs/graphql'; import { UserRole } from 'src/schemas/userRole.schema'; import { BaseDTO } from 'src/shared/dto/base.dto'; import { PagedResultDTO } from 'src/shared/dto/pagedResult.dto'; // 原有的ObjectType基础类保持不变 @ObjectType({ isAbstract: true }) export class UserBaseDTO { @Field() public email: string; @Field() public username: string; @Field() public password: string; @Field(() => String, { nullable: true }) public role: UserRole; } // 新增:User的InputType基础类 @InputType({ isAbstract: true }) export class UserBaseInputDTO { @Field() public email: string; @Field() public username: string; @Field() public password: string; @Field(() => String, { nullable: true }) public role: UserRole; } // 原有的ObjectType UserDTO保持不变 @ObjectType() export class UserDTO extends IntersectionType( UserBaseDTO, BaseDTO, ObjectType, ) {} // 新增:完整的User InputDTO @InputType() export class UserDTOInput extends IntersectionType( UserBaseInputDTO, // 注意:如果BaseDTO是ObjectType,这里需要替换为对应的BaseInputDTO(比如只保留更新时需要的字段) InputType, ) {} // 原有的其他User Input类保持不变 @InputType() export class CreateUserInputDTO extends OmitType( UserBaseDTO, ['role'] as const, InputType, ) {} @InputType() export class UpdateUserInputDTO extends PartialType(UserDTO, InputType) {} @ObjectType() export class UsersPagedResultDTO extends PagedResultDTO<UserDTO> { @Field(() => [UserDTO]) public records: UserDTO[]; }
步骤2:拆分Post的基础DTO,区分Object/Input场景
在post.dto.ts中,拆分出Object专用和Input专用的基础类,避免类型混用:
import { Field, InputType, IntersectionType, ObjectType, PartialType, } from '@nestjs/graphql'; import { BaseDTO } from 'src/shared/dto/base.dto'; import { PagedResultDTO } from 'src/shared/dto/pagedResult.dto'; import { UserDTO, UserDTOInput } from '../user/user.dto'; // ObjectType专用的Post基础类 @ObjectType({ isAbstract: true }) export class PostBaseObjectDTO { @Field() title: string; @Field() description: string; @Field() headerPhoto: string; @Field() content: string; @Field() komootId: string; @Field() date: Date; @Field(() => [String]) keyword: string[]; @Field(() => UserDTO, { nullable: true }) author?: UserDTO; } // InputType专用的Post基础类 @InputType({ isAbstract: true }) export class PostBaseInputDTO { @Field() title: string; @Field() description: string; @Field() headerPhoto: string; @Field() content: string; @Field() komootId: string; @Field() date: Date; @Field(() => [String]) keyword: string[]; @Field(() => UserDTOInput, { nullable: true }) author?: UserDTOInput; } // ObjectType的PostDTO,继承Object专用基础类 @ObjectType() export class PostDTO extends IntersectionType( PostBaseObjectDTO, BaseDTO, ObjectType, ) {} // InputType的CreatePostInputDTO,继承Input专用基础类 @InputType() export class CreatePostInputDTO extends IntersectionType( PostBaseInputDTO, // 若创建帖子时不需要BaseDTO的字段(如_id、createdAt),可移除该继承 InputType, ) {} // 修改UpdatePostInputDTO,基于Input专用基础类生成 @InputType() export class UpdatePostInputDTO extends PartialType(PostBaseInputDTO, InputType) {} @ObjectType() export class PostsPagedResultDTO extends PagedResultDTO<PostDTO> { @Field(() => [PostDTO]) public records: PostDTO[]; }
可选优化:简化关联字段
如果创建/更新帖子时,只需要关联用户的ID而非完整用户对象,可直接将Input类中的author字段改为ID类型:
@InputType({ isAbstract: true }) export class PostBaseInputDTO { // 其他字段... @Field(() => String, { nullable: true }) authorId?: string; }
这种方式更符合GraphQL的输入场景,减少不必要的数据传输。
内容的提问来源于stack exchange,提问作者theboyonfire
相关产品推荐
相关产品推荐

