Encountering an issue with typescript involving a mongoose model that is interface casted.
import { Schema, model } from "mongoose";
interface IUser {
userId: string
guildId: string
cash: number
bank: number
}
const userSchema = new Schema<IUser>({
userId: { type: String, required: true },
guildId: { type: String, required: true },
cash: { type: Number, required: true },
bank: { type: Number, required: true }
});
const User = model<IUser>("User", userSchema);
export default User;
Facing an error in typescript when attempting to access properties like userDocument.cash
even after finding and importing a document from the collection, resulting in an Object is possibly 'null'
error:
import UserModel from "path/to/model";
// some code (not relevant)
if (!(UserModel.findOne({ userId: user.id, guildId: i.guildId }))) newUser(i.guild!, user);
const userDocument = await UserModel.findOne({ userId: user.id, guildId: i.guildId });
console.log(userDocument.cash) // typescript error: Object is possibly 'null'
// ~~~~~~~~~~~~
To address this issue, looking for a way to explicitly declare to typescript that the variable is not null without repetitively using the !
operator.
Explored two workarounds with varying degrees of success:
- Casting the IUser interface onto the userDocument but losing access to other document-related properties/methods:
const userDocument = await UserModel.findOne({ userId: user.id, guildId: i.guildId }) as IUser;
userDocument.cash = 300;
userDocument.save() // typescript error: Property 'save' does not exist on type 'IUser'.
// ~~~~
- An alternative workaround involves reassigning the userDocument variable which is functional but unappealing:
let userDocument = await UserModel.findOne({ userId: user.id, guildId: i.guildId });
userDocument = userDocument!
userDocument.cash = 300;
userDocument.save() // works
Referencing solutions found in this post, however, struggling to implement them effectively in this scenario.