Typegoose: MongooseArray.pull is not recognised on Documents

Created on 14 May 2020  路  5Comments  路  Source: typegoose/typegoose

Versions

  • NodeJS: v12.x
  • Typegoose(NPM): 7.0.0
  • mongoose: 5.9.10

What is the Problem?

I think there is some incomplete typing going in with arrays of subdocuments. See example.

class UserSchema {
    @arrayProp({required: true, default: [], items: ProfilePictureSchema})
    pictures: ProfilePictureSchema[];

    public removePicture(pictureId: string) {
        this.pictures.pull(pictureId);
    }
}

Results in the Typescript error:

src/models/user.ts:178:17 - error TS2339: Property 'pull' does not exist on type 'ProfilePictureSchema[]'.

this.pictures.pull is a MongooseArray method, yet the resulting typegoose document doesn't recognise it.

Do you know why it happenes?

no

question

All 5 comments

Duplicate of #255

Great stuff, thanks!

I'm afraid I have a follow-up problem that belongs in the same thread. The solution in #255 works fine for normal arrays. However, I fail to get this solution to work satisfactorily with arrays of references.

This simply doesn't work:

class Meetup {
    @arrayProp({required: true, items: String, ref: User, refType: mongoose.Schema.Types.String})
    attendees: Ref<User>[];
}
const meetup: DocumentType<Meetup> = MeetupModel.findOne({});
meetup.attendees.toObject() // <--- Error: Property 'toObject' does not exist on type 'Ref<User, string>[]'

I was trying to be clever so I tried the following, which also doesn't quite work

class Meetup {
    @arrayProp({required: true, items: String, ref: User, refType: mongoose.Schema.Types.String})
    attendees: Ref<User>[] | mongoose.Types.Array<string>;
}
const meetup: DocumentType<Meetup> = MeetupModel.findOne({});
meetup.attendees.toObject() // <--- Error: Property 'toObject' does not exist on type 'Ref<User, string>[] | Array<string>

Now, the following does sort of work alright, but I'm worried about losing my nice Ref type.

class Meetup {
    @arrayProp({required: true, items: String, ref: User, refType: mongoose.Schema.Types.String})
    attendees: mongoose.Types.Array<string>;
}

So what would be the ideal way to go about this?

{required: true, items: String, ref: User, refType: mongoose.Schema.Types.String}

items & of & refType are an alias for type, which overwrite eachother
(items is only an alias if design:type is an Array-Like and of is only an alias if design:type is an Map-Like)
(current order: type gets overwritten by refType and gets overwritten by items/of)


could you provide the User class?


commit 2242b63b6ea77500b9b21184a68eb5219bedb9a7 added an test, this might be what you are looking for

Thanks on the first note, I changed it.

I then pulled the commit you mentioned, and made the following change according to the deprecation of arrayProp

    @prop({required: true, ref: User, refType: mongoose.Schema.Types.String}, WhatIsIt.ARRAY)

Following #255, I tried the following

    attendees: mongoose.Types.Array<Ref<User>>;

which works! meetup.attendees is now of type mongoose.Types.Array<Ref<User>>. This is exactly what I needed. At first I thought I needed a DocumentArray (for when the array is populated) but of course that didn't work.

Cheers!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

huming2207 picture huming2207  路  8Comments

DanielEberl picture DanielEberl  路  5Comments

remidej picture remidej  路  7Comments

kerolloz picture kerolloz  路  6Comments

Negan1911 picture Negan1911  路  10Comments