如何将Prisma的Json类型字段映射到TypeGraphQL自定义对象类型?
解决方案
这种定义方式完全可行,核心是在Prisma数据和TypeGraphQL类型之间做手动类型转换——因为Prisma返回的Json?字段对应Prisma.JsonValue类型,和你定义的Comment[]类型不兼容,必须显式转换才能匹配TypeGraphQL的类型要求。
具体实现步骤
1. 实现类型转换工具函数
先写一套工具函数,负责JSON数据和Comment类型的双向转换,同时加入类型校验避免运行时错误:
import { Prisma } from '@prisma/client'; import { Comment } from './types'; // 类型守卫:检查对象是否符合Comment结构 function isComment(obj: unknown): obj is Comment { return ( typeof obj === 'object' && obj !== null && 'id' in obj && typeof (obj as Comment).id === 'number' && 'content' in obj && typeof (obj as Comment).content === 'string' ); } // 把Prisma返回的JsonValue转换成Comment[] export function parseComments(comments: Prisma.JsonValue | null | undefined): Comment[] | null { if (!comments) return null; if (!Array.isArray(comments)) return null; // 验证每个元素的结构合法性 return comments.every(isComment) ? (comments as Comment[]) : null; } // 把Comment[]转换成Prisma可存储的JsonValue export function stringifyComments(comments: Comment[] | null | undefined): Prisma.JsonValue | null { if (!comments) return null; return JSON.parse(JSON.stringify(comments)) as Prisma.JsonValue; }
2. 修改Resolver完成类型映射
你原来的Resolver直接返回了Prisma的PostDb类型,和TypeGraphQL定义的Post类型不匹配,需要手动转换字段:
import { Post as PostDb } from '@prisma/client'; import { Post, Comment } from './types'; import { parseComments, stringifyComments } from './utils'; @Resolver(Post) export class PostResolver { @Query((returns) => Post, { nullable: true }) async getPostByTitle(@Arg('title') title: string): Promise<Post | null> { try { const postDb = await prismaClient.post.findUnique({ where: { title } }); if (!postDb) return null; // 转换PostDb到Post类型,重点处理comments字段 return { ...postDb, comments: parseComments(postDb.comments) }; } catch(error) { throw new GetPostError(error.message); } } // 示例:创建Post时的反向转换 @Mutation((returns) => Post) async createPost( @Arg('title') title: string, @Arg('content') content: string, @Arg('comments', { nullable: true }) comments?: Comment[] ): Promise<Post> { const postDb = await prismaClient.post.create({ data: { title, content, comments: comments ? stringifyComments(comments) : null } }); return { ...postDb, comments: parseComments(postDb.comments) }; } }
3. 解决TypeScript类型报错
通过上述转换,Resolver返回的类型完全匹配TypeGraphQL定义的Post类型,TypeScript的类型不兼容错误会直接消失。同时isComment类型守卫能确保从JSON解析出来的数据符合预期结构,避免非法数据导致运行时异常。
关键注意事项
- 必须处理双向转换:查询时把JSON转成
Comment[],写入时把Comment[]转成JSON格式。 - 类型守卫是可选但推荐的:用于验证JSON数据的结构合法性,避免脏数据引发问题。
- 不要直接返回Prisma模型:TypeGraphQL依赖你定义的
@ObjectType()类,必须做字段映射转换。
内容的提问来源于stack exchange,提问作者jenwoodson
相关产品推荐
相关产品推荐

