Mongoose Schema中添加枚举类型时出现类型不匹配错误,求解决方法
嘿,这个问题我之前也碰到过,其实就是枚举类型的定义和Mongoose Schema的类型没对齐导致的,我给你拆解一下原因和解决办法:
问题根源
你定义的Category是TypeScript默认的数字枚举,这种枚举会自动给成员分配数字值(比如Sadaqah对应0,Zakat对应1),而且TypeScript还会生成反向映射,所以Object.values(Category)会返回["Sadaqah", "Zakat", 0, 1]——这个数组里既有字符串又有数字,和你Schema里指定的type: Schema.Types.String完全不兼容。另外你的Appeal接口里category是Category类型(也就是数字),但Schema里却设成了String类型,这也造成了类型层面的冲突,难怪TypeScript会报错。
解决办法
我给你两种靠谱的解决方案,你可以根据需求选:
方法一:改成字符串枚举(更推荐)
把Category改成字符串枚举,这样既能保证枚举值是你想要的字符串,又能让Object.values(Category)只返回字符串数组,和Schema的String类型完美匹配:
修改appealTypes.ts:
import { Types } from "mongoose"; // 显式指定枚举值为字符串,变成字符串枚举 export enum Category { Sadaqah = "Sadaqah", Zakat = "Zakat", } export interface Appeal { _id: string; category: Category; }
appealModel.ts可以保持原样,也可以把Schema.Types.String简化成String,效果是一样的:
import mongoose, { Schema } from 'mongoose'; import { Appeal, Category } from './appealTypes' const appealSchema = new mongoose.Schema<Appeal>( { category: { type: String, enum: Object.values(Category), required: true, }, }, { timestamps: true } ); export default mongoose.model<Appeal>('Appeal', appealSchema)
方法二:保留数字枚举,调整Schema配置
如果你非要用数字枚举,那得把Schema的类型改成Number,还要过滤掉Object.values(Category)里的字符串反向映射值,只保留数字:
修改appealModel.ts:
import mongoose, { Schema } from 'mongoose'; import { Appeal, Category } from './appealTypes' // 过滤出枚举里的数字值,去掉反向映射的字符串 const categoryEnumValues = Object.values(Category).filter(v => typeof v === 'number') as Category[]; const appealSchema = new mongoose.Schema<Appeal>( { category: { type: Number, // 类型改成Number enum: categoryEnumValues, required: true, }, }, { timestamps: true } ); export default mongoose.model<Appeal>('Appeal', appealSchema)
验证效果
不管用哪种方法,你之后保存数据时,传入Category.Sadaqah或者对应的字符串/数字,Mongoose都会正确做枚举校验,TypeScript的类型错误也会消失啦。
备注:内容来源于stack exchange,提问作者Fuaad

