在Nexus中如何为GraphQL定义类型安全的createdAt和updatedAt?
解决Prisma DateTime与Nexus GraphQL类型不兼容问题
问题原因
Prisma Schema中定义的DateTime类型,在TypeScript中会被编译为Date对象,但GraphQL本身没有内置的DateTime标量:
- 直接用
string类型:TypeScript会报错Date无法赋值给string - 用
int类型:毫秒级时间戳(如1661894591365)超出GraphQLInt的32位有符号整数范围(最大值为2147483647)
可行解决方案
方案1:使用nexus-prisma自动生成字段(推荐)
如果你已经集成了nexus-prisma,无需手动定义createdAt/updatedAt字段,直接使用Prisma模型生成的类型即可,它会自动处理Date到GraphQL可识别类型的转换:
import { objectType } from 'nexus' export const Post = objectType({ name: 'Post', definition(t) { // 直接使用nexus-prisma生成的字段,无需手动指定类型 t.model.id() t.model.createdAt() t.model.updatedAt() // 其他字段... }, })
方案2:自定义DateTime标量
自己定义一个DateTime标量,处理Date与ISO字符串的双向转换:
- 定义标量类型
import { scalarType } from 'nexus' export const DateTime = scalarType({ name: 'DateTime', asNexusMethod: 'dateTime', description: '日期时间类型,以ISO 8601字符串格式返回', parseValue(value) { // 从客户端接收值时转换为Date return new Date(value) }, serialize(value) { // 向客户端返回时转换为ISO字符串 return (value as Date).toISOString() }, parseLiteral(ast) { // 解析GraphQL字面量 if (ast.kind === 'StringValue') { return new Date(ast.value) } return null }, })
- 在schema中使用自定义标量
t.nonNull.dateTime('createdAt') t.nonNull.dateTime('updatedAt')
方案3:手动处理类型转换
如果不想自定义标量,可以在resolve函数中把Date对象转为ISO字符串,同时指定类型为String:
t.nonNull.field('createdAt', { type: 'String', resolve: (parent) => parent.createdAt.toISOString(), }) t.nonNull.field('updatedAt', { type: 'String', resolve: (parent) => parent.updatedAt.toISOString(), })
内容的提问来源于stack exchange,提问作者Atharv Kurdukar
相关产品推荐
相关产品推荐

