I have an interface like this.
export interface IMerchant{
id?:string,
name:string,
surname:string,
mail:string,
}
My schema like this
import { Schema, model, Model } from 'mongoose';
interface IMerchantModel extends Model<IMerchant> {
getAllMerchants(): IMerchant[];
setMerchant(merchant:IMerchant):IMerchant;
}
const merchantSchema = new Schema<IMerchant, IMerchantModel>({
name: { type: String, required: true },
surname:{type:String,required:true},
mail:{type:String,required:true},
},
{
timestamps: { createdAt: "createdDate", updatedAt: "updatedDate" },
toJSON: { virtuals: true },
});
const Merchant = model<IMerchant, IMerchantModel>('Merchant', merchantSchema);
export default Merchant;
My main goal is create a data if not exist or update it if exist.
merchantSchema.static('setMerchant', async function setMerchant(merchant:IMerchant) {
try{
if(merchant.id){
// if object has id field get from collection.
let m = await this.findOne({ id: merchant.id }) as IMerchant;
if (m) {
m={...merchant};
m.save();
//Error -> Property 'save' does not exist on type 'IMerchant'.
}
return m;
}
else{
// if not exist, create one
const newData= new Merchant(merchant);
const savedData=await newData.save();
return savedData;
}
}
catch(e){
// throw an Error
}
});
So main problem in update I got an error.
Property 'save' does not exist on type 'IMerchant'.
How can I cast return data from findOne
CodePudding user response:
According this documentation mongoose doesn't suggest extends Document.
Alternatively, your document interface can extend Mongoose's Document class.
We strongly recommend against using this approach, its support will be dropped in the next major version as it causes major performance issues. Many Mongoose TypeScript codebases use the below approach.
import { Document, Schema, model, connect } from 'mongoose'; interface IUser extends Document { name: string; email: string; avatar?: string; }
Thus, HydratedDocument can be solution.
import { Schema, model, Model, HydratedDocument } from 'mongoose';
change from
let m = await this.findOne({ id: merchant.id }) as IMerchant;
to
let m = await this.findOne({ id: merchant.id }) as HydratedDocument<IMerchant>;