使用 TypeScript 枚举类型配合 Mongoose 模式(schema)

5

我有一个包含枚举的模式:

export interface IGameMapModel extends IGameMap, Document {}

export const gameMapSchema: Schema = new Schema({
  name: { type: String, index: { unique: true }, required: true },
  type: { type: String, enum: CUtility.enumToArray(GameMode) }
});

export const GameMap: Model<IGameMapModel> = model<IGameMapModel>('GameMap', gameMapSchema);

GameMap 是一个枚举类型。

首先,我需要将枚举转换为字符串数组才能与模式一起使用。

其次,在模式创建期间,我希望直接使用枚举值。

new GameMap({
  name: 'Test',
  type: GameMode.ASSAULT
});

返回 ValidationError:type:“1”不是路径“type”的有效枚举值。

由于我在模型枚举属性中设置了字符串数组,因此我不确定这是否实际可行。

我的想法是在模式创建过程中创建某种类型转换。这样做可以使用mongoose吗?还是我需要创建对象创建的某种帮助程序?

2个回答

6

GameMode.ASSAULT 被解析为它的数字值,但是 GameMode 期望类型为字符串。你期望字符串解析的结果是什么?如果你需要枚举的字符串值,你可以通过 GameMode[GameMode.ASSAULT] 访问它,它会返回一个字符串 ASSAULT

例如:

enum TEST {
    test1 = 1,
    test2 = 2
}

console.log(TEST[TEST.test1]);
//Prints "test1"

Mongoose验证文档 可以看出,在模式属性中,如果一个类型为字符串的枚举需要进行验证,则Mongoose期望得到一个由字符串组成的数组。
这意味着 CUtility.enumToArray(GameMode) 需要返回一个由索引字符串或者是enum的文本/字符串值组成的数组,取决于您希望在数据库中存储哪种类型。
验证错误似乎暗示了 CUtility.enumToArray(GameMode) 产生的数组不包含 1,或者验证器认为 GameMode.ASSAULT 是一个数字而不是预期的表示为 1 的字符串。您可能需要将传入的enum值转换为字符串。 CUtility.enumToArray(GameMode) 的输出是什么?这应该有助于确定您遇到的问题。

我的最后一句话包含了我的问题,如果您能阅读我的问题并可能更新您的答案,我将不胜感激。 - Jannis Lehmann
你期望"type"参数是什么?有例子吗? - user8086575
1
由于模式,它必须是一个字符串。我的问题是是否有可能提供枚举并由mongoose或我创建的某个函数进行转换。 - Jannis Lehmann
1
有点是的。CUtility.enumToArray(GameMode) 返回 ['ASSAULT','MORE']。我知道为什么会返回 TypeError,但我想知道是否有一种方法可以使用 new Test({type: GameMode.ASSAULT}) 创建一个对象,并且 mongoose 或其他帮助方法将其转换为字符串,这样我就不必每次都使用 GameMode[GM.Assault] 了。 - Jannis Lehmann
我认为你可能只需要创建自己的辅助方法,但通过抽象它来节省代码可能并不多。 - user8086575

2

为什么不创建自定义的getter/setter:


const schema = new Schema ({
    enumProp: {
            type: Schema.Types.String,
            enum: enumKeys(EnumType),
            get: (enumValue: string) => EnumType[enumValue as keyof typeof EnumType],
            set: (enumValue: EnumType) => EnumType[enumValue],
        },
});

编辑: 不要忘记显式地启用getter

schema.set('toJSON', { getters: true }); 
// and/or
schema.set('toObject', { getters: true });

这样你就可以精确控制如何在数据库、后端和前端(JSON响应)中表示该属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接