Ask questions[mongoose] problems using generic type (<T extends Document>)

  • [x] I tried using the @types/mongoose package and had problems.
  • [x] I tried using the latest stable version of tsc.
  • [x] I have a question that is inapprsuopriate for StackOverflow. (Please ask any appropriate questions there).
  • [x] Mention the authors (see Definitions by: in index.d.ts) so they can respond.
    • Authors: @horiuchi @lukasz-zak @jendrikw @ethanresnick @vologab @jussikinnula @ondratra @alfirin @idandrd @various89 @Fazendaaa @NormanPerrin @stablio @emmanuelgautier @frontendmonster @mingchen @penumbra1 @HughKu @niuware @vladmel1234 @jloveridge @grimmer0125 @richarddd @ToucheSir @borfig @dinodeSimon @anthony-kenikh @iamchathu @lkho @tomyam1 @nephix @rlaace423 @ChazEpps @avaly @JanNemcik @cl3dson @richardsimko @ith @jeremyben @andreialecu @tHBp

Hey! I've updated @types/mongoose to v5.7.34. I believe there is a bug when using generic types.

Let's say I have this document, model and data:

interface User {
    name: string;
    password: string;
type UserDocument = User & Document;
const schema = new Schema({name: {type: String}, password: {type: String}});
const userModel: Model<UserDocument> = model('User', schema);
const user: User = {name: "someName", password: '********'};

These functions work as expected:

const typedFindById = async (model: Model<UserDocument>, inputId: string) => {
    model.find({id: inputId});
typedFindById(userModel, 'someId');

const typedCreateDoc = async (model: Model<UserDocument>, doc: User) => {
    return model.create(doc);
typedCreateDoc(userModel, user);

I need to wrap those functions for any type extending Document. In the past versions (v5.5.X) of @types/mongoose, I've used it like this:

const genericFindById = async <T extends Document>(model: Model<T>, inputId: string) => {
    return model.find({id: inputId});
    // Argument of type '{ id: string; }' is not assignable to parameter of type 'MongooseFilterQuery<Pick<T, Exclude<keyof T, "toString" |...
    // Type '{ id: string; }' is not assignable to type '{ [P in keyof Pick<T, Exclude<keyof T, "toString" | ...
genericFindById(userModel, 'someId');

const genericCreateDoc = async <A, T extends Document & A>(model: Model<T>, doc: A) => {
    return model.create(doc);
    // Argument of type 'A' is not assignable to parameter of type 'CreateQuery<T>'.
genericCreateDoc(userModel, user);

I'm not able to figure out why this happens. I believe this is a correct implementation. Is this a bug?

Thanks for your reply!


Answer questions avaly

AFAIK mongoose.Document has _id: any. If you defined your _id in your model interface as ObjectId or string, it should work. :crossed_fingers:

Github User Rank List