升级至TS 5.3.0 + NestJS 9 + @nestjs/graphql 11后,PickType生成空GraphQL输入类型的问题求助
升级至TS 5.3.0 + NestJS 9 + @nestjs/graphql 11后,PickType生成空GraphQL输入类型的问题求助
大家好,我最近把项目技术栈做了升级,当前使用的版本组合是:
- TypeScript 5.3.0(已开启
"experimentalDecorators": true和"emitDecoratorMetadata": true) - NestJS v9 搭配
@nestjs/graphql@11.x - MikroORM v6 结合 MongoDB
之前在TS 4 + Nest 8 + @nestjs/graphql@10的环境下,我可以通过工具函数继承实体类,再用PickType(...)提取特定字段动态构建GraphQL更新输入类型,一切都正常。但升级之后,生成的输入类型居然完全是空的,连一个字段都没有,这可把我难住了。
先给大家展示我的代码结构:
Product 实体类
import { Entity, PrimaryKey, Property } from '@mikro-orm/core'; import { ObjectType, Field, ID } from '@nestjs/graphql'; import { IsString, IsNumber, IsBoolean } from 'class-validator'; @ObjectType() @Entity({ tableName: 'product' }) export class Product { @Field(() => ID) @PrimaryKey() id!: string; @Field() @Property() @IsString() name!: string; @Field({ nullable: true }) @Property({ nullable: true }) @IsNumber() price?: number; @Field({ nullable: true }) @Property({ nullable: true }) @IsBoolean() available?: boolean; // …其他属性… }
动态生成输入类型的工具函数
// src/utils/dto/create-update-input-type.ts import { PartialType, PickType } from '@nestjs/graphql'; import { Type } from '@nestjs/common'; export function CreateUpdateInputType< E, K extends readonly (keyof E)[] >( entityClass: Type<E>, keys: K, ): Type<Partial<Pick<E, K[number]>>> { return PartialType(PickType(entityClass, keys)) as any; }
Product 的输入参数定义
// src/dto/product.args.ts import { ArgsType, Field, InputType } from '@nestjs/graphql'; import { CreateUpdateInputType } from '@src/utils/dto'; import { Product } from '@src/entities/product.entity'; import { IsMongoId, IsOptional, ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; const updateFields = ['name', 'price', 'available'] as const; @InputType() class UpdateProductInput extends CreateUpdateInputType( Product, updateFields, ) {} @ArgsType() export class UpdateProductArgs { @Field() @IsMongoId() @IsOptional() id?: string; @Field(() => UpdateProductInput) @ValidateNested() @Type(() => UpdateProductInput) data!: UpdateProductInput; }
我的 tsconfig 核心配置
{ "compilerOptions": { "target": "ES2020", "module": "CommonJS", "experimentalDecorators": true, "emitDecoratorMetadata": true, // …其他配置项… } }
问题现象对比
在升级前的TS 4 + Nest 8环境下,生成的GraphQL SDL完全符合预期:
input UpdateProductInput { name: String price: Float available: Boolean }
但升级到新环境后,生成的SDL里输入类型完全是空的:
input UpdateProductInput
我实在搞不懂原因,明明满足这些前提:
- Product类已经用
@ObjectType()装饰 - 每个要提取的字段都有对应的
@Field()装饰器 updateFields是用as const声明的只读元组,类型定义正确- 我是在
await app.init()之后才去查看SDL的
如果说是TS 5改变了装饰器元数据的继承逻辑,那直接对Product类调用PickType为什么也识别不到原类的字段呢?之前在Nest v11之前或者旧版TS里,完全不需要在子类上重新加@Field()就能正常生成输入类型啊。
有没有大佬知道@nestjs/graphql@11或者TypeScript 5.x里的某个变更,能解释这个运行时元数据丢失的问题?
内容来源于stack exchange
相关产品推荐
相关产品推荐

