使用带有mongoose模式的TypeScript枚举

时间:2017-05-31 17:09:41

标签: node.js mongodb typescript mongoose enums

我有一个带枚举的架构:

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' is not a valid enum value for path 'type'.

由于我在模型枚举属性中设置的字符串数组,我不确定这是否真的有效。

我的想法是在架构创建过程中创建某种类型的转换。这是用于mongoose还是我必须为对象创建创建某种帮助?

2 个答案:

答案 0 :(得分:2)

GameMode.ASSAULT正在评估其数值,但GameMode期望该类型为字符串。您对字符串评估的期望是什么?如果您需要枚举的字符串值,可以使用GameMode[GameMode.ASSAULT]访问它,这将返回ASSAULT字符串。

例如:

enum TEST {
    test1 = 1,
    test2 = 2
}

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

来自Mongoose docs on validation,在type String具有enum验证的架构属性中,mongoose在字符串数组中需要的enum

这意味着CUtility.enumToArray(GameMode)需要以字符串形式返回索引数组,或者enum的文本/字符串值数组 - 无论您希望存储在哪一个中你的数据库。

验证错误似乎意味着1未包含CUtility.enumToArray(GameMode)正在生成的数组中,或者验证是GameMode.ASSAULT作为预期的数字1 enum的字符串表示形式。您可能必须将传入的CUtility.enumToArray(GameMode)值转换为字符串。

exports.addBulkSite = function(req, res, next) { let siteArray = csv.parse((req.body.sites).trim()), addedSites = [], failedSites = [], duplicated = [], sites = siteArray, size = sites.length, processed = 0, meta; Promise.each(sites, sites => new Promise((resolve, reject) => { let name = tools.extractDomain(req, res, sites[0]), country = sites[1], group = sites[2]; if (name != "" && country != "" && group != "") { Site.findOneAsync({ name: name }, "_id").then(function(duplicate) { duplicated.push(duplicate); reject({name:name, message: 'Duplicated', critical:false}); }).catch(function(notDuplicated){ let site = new Site() site = { name: name, meta: {}, group: group, country: country, geomix:{}, addedBy: req.user._id, addedAt:Date.now() } site.saveAsync().then(function(response){ tools.saveHistory(req, res, response._id, response.name, "Website Meta fetched."); tools.saveHistory(req, res, response._id, response.name, "Link added for the first time."); //Save in history resolve(site); }).catch(function (e){ console.log(e); reject({name:name, message: 'Error saving in the database. Please contact the administrator.', critical: true}); }); }); }else{ reject({name:name, message: 'Paramaters are missing', critical:false}); } }).then((data) => { processed++; addedSites.push(data); if(processed==size){ console.log('out'); res.send({ status: 'ok', addedSites: addedSites, failedSites: failedSites, duplicated: duplicated}); } }).catch((err) => { processed++; console.log(err); failedSites.push(err); if(processed==size){ console.log('out'); res.send({ status: 'ok', addedSites: addedSites, failedSites: failedSites, duplicated: duplicated}); } })); } 的输出是什么?这应该可以帮助您确定这两个问题中的哪一个。

答案 1 :(得分:0)

为什么不创建自定义的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],
        },
});

编辑: 不要忘记明确启用吸气剂

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

通过这种方式,您可以精细地控制要在数据库,后端和前端(json响应)中表示道具的精确度。