Reputation: 2089
The ts compiler says that none of the properties exist on type 'Document'.
It seems that because of this none of the properties on the model can be set. If I print a user object to the console all I get is {"_id":"long hex id number"}
My model is configured as follows:
users.ts
import * as mongoose from 'mongoose';
import * as crypto from 'crypto';
import * as jwt from 'jsonwebtoken';
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
firstMidname: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
hash: String,
salt: String
});
userSchema.methods.setPassword = setPassword;
userSchema.methods.validPassword = validPassword;
userSchema.methods.generateJwt = generateJwt;
export = mongoose.model('User', userSchema);
Api connection point api.ts
import * as express from 'express';
import * as mongoose from 'mongoose';
import * as passport from 'passport';
var User = mongoose.model('User');
var router = express.Router();
router.post('/', createUser);
function createUser(req, res){
var user = new User();
console.log(user);
user.firstMidName = req.body.firstName;
user.lastName = req.body.lastName;
user.setPassword(req.body.password);
user.save((err) => {
console.log("saving user");
var token;
token = user.generateJwt();
res.status(200);
res.json({
'token': token
});
});
}
export = router;
How can I fix or troubleshoot this issue? Nothing in the user.save
block executes.
EDIT: The two things seem to be unrelated. I can now save to the database however the typescript error persists. Is this expected behaviour?
Upvotes: 19
Views: 34005
Reputation: 11
As clearly stated by @creme332, the findByIdAndRemove()
method is only available in mongoose v7, and entirely removed in mongoose v8.
use findByIdAndDelete()
instead. it work just find without extending any class.
Upvotes: 0
Reputation: 1935
I had the Post
model defined as follows:
import mongoose from "mongoose";
export interface iPost {
title: string;
}
const Schema = mongoose.Schema;
const PostSchema = new Schema<iPost>({
title: {
type: String,
}
});
export default mongoose.model("Post", PostSchema);
I tried using Post.findByIdAndRemove(...);
but got the following error:
Property 'findByIdAndRemove' does not exist on type 'Model<iPost, {}, {}, {}, Document<unknown, {}, iPost> & iPost & { _id: ObjectId; }, Schema<iPost, Model<iPost, any, any, any, Document<unknown, any, iPost> & iPost & { ...; }, any>, ... 6 more ..., Document<...> & ... 1 more ... & { ...; }>>'.
I tried making my iPost
interface extend mongoose.Document
as suggested by the other answers but it did not work.
The findByIdAndRemove()
method is only available in mongoose v7 while I was using mongoose v8. The equivalent method for mongoose v8 is findByIdAndDelete()
.
In Mongoose v8, there is also no need to make your interface extend mongoose.Document
.
Use the mongoose documentation for your mongoose version to verify that the mongoose property that you are trying to use actually exists.
Upvotes: 0
Reputation: 653
Fixed this by adding interface upon declaration of schema
interface UserInterface extends Document {
email: string;
}
const User = new Schema<UserInterface>({
email: String;
})
Upvotes: 1
Reputation: 4170
When I defined my entity interface I had it extending "Document" but had not imported anything.
When I crtl+click on it though I can see that it incorrectly thinks I was referring to the built-in node object "Document":
/** Any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree. */
interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShadowRoot, GlobalEventHandlers, NonElementParentNode, ParentNode, XPathEvaluatorBase {
After I explicitly told it to use Document from the mongoose library things worked. 👍
import { Document } from 'mongoose';
Upvotes: 2
Reputation: 780
The mongoose.model
method accepts a type that defaults to mongoose.Document
, which won't have properties you want on your User
document.
To fix this, create an interface that describes your schema and extends mongoose.Document
:
export interface UserDoc extends mongoose.Document {
email: {
type: string;
unique: boolean;
required: boolean;
}
...
}
Then, pass that through as the type for your model:
export = mongoose.model<UserDoc>('User', userSchema);
Upvotes: 24