NestJS GraphQL ResolveField实现creationDate格式化参数返回字符串报错
问题产生原因
- 字段返回类型与Schema定义不匹配:你使用的是GraphQL Code First开发模式,原
Recipe实体的creationDate字段被声明/推断为非空Date类型,但你在ResolveField逻辑中传入format参数时返回的是字符串类型,GraphQL执行阶段无法将字符串识别为合法的Date类型值,最终返回null,触发非空字段的校验规则抛出错误。 - 未显式声明ResolveField返回类型:你没有给
@ResolveField装饰器指定明确的返回类型,NestJS的类型推断逻辑无法匹配「有时返回Date、有时返回String」的逻辑,进一步加剧了类型校验失败的问题。 - 潜在小问题:如果
recipe.creationDate本身是无效日期,moment().format()会返回Invalid Date异常值,也可能触发校验报错。
解决方案
方案1:统一将creationDate返回类型改为字符串(推荐,适配格式化需求)
因为你需要支持自定义日期格式化,将字段统一为字符串类型更符合使用场景,修改两处代码即可:
- 给ResolveField显式指定返回类型为非空字符串,同时补全日期有效性校验:
@ResolveField(() => String, { nullable: false }) async creationDate( @Parent() recipe: Recipe, @Args('format', { nullable: true }) format?: string) { const date = moment(recipe.creationDate); if(!date.isValid()) return ''; // 可替换为你需要的默认日期值 return format ? date.format(format) : date.toISOString(); }
- 同步修改
Recipe实体类中creationDate字段的类型声明,保持类型一致:
// 原有@Field(() => Date)替换为String类型 @Field(() => String, { description: '创建日期,支持format参数自定义格式化规则' }) creationDate: string;
方案2:新增独立的格式化日期字段
如果你需要保留原creationDate的Date类型,可以新增专门的格式化字段,避免修改原有逻辑:
// Resolver中新增字段 @ResolveField(() => String, { nullable: false }) async formattedCreationDate( @Parent() recipe: Recipe, @Args('format', { nullable: true, defaultValue: 'YYYY-MM-DD' }) format: string) { const date = moment(recipe.creationDate); return date.isValid() ? date.format(format) : ''; }
查询时调用新字段即可:
query { recipes { id, title, ingredients, creationDate # 保留原有Date类型返回 formattedCreationDate(format: "YYYY-MM-DD") # 自定义格式化的字符串返回 } }
内容的提问来源于stack exchange,提问作者鸿则_
相关产品推荐
相关产品推荐

