0

I've been trying to create a plugin which implements a query and schema method that populates a user field and selects some inner fields from it (firstName, lastName, image).

I just can't seem to make it work out with typescript. when using this plugin's methods, the returned object isn't typed properly with the populated fields,the field's type is still ObjectId.

This is what I came up to at this point:

import { Document, HydratedDocument, Model, QueryWithHelpers, Schema } from 'mongoose';
import { UserSummary } from 'src/modules/behaviors/dto/user-summary.interface';

const populatedFields = 'firstName lastName email image';

export interface PopulateUserQuery<Model> {
  populateUser(
    field: string
  ): QueryWithHelpers<HydratedDocument<Model>[], HydratedDocument<Model>, PopulateUserQuery<Model>>;
}

export interface PopulateUserMethod<Model> {
  populateUser(field: string): Promise<HydratedDocument<Model>>;
}

export function populateUserSummary<
  EnforcedDocType,
  TModelType = Model<EnforcedDocType>,
  TInstanceMethods = object,
>(
  schema: Schema<
    EnforcedDocType,
    Model<EnforcedDocType>,
    TInstanceMethods,
    PopulateUserQuery<TModelType>
  >
) {
  schema.query.populateUser = function (
    this: QueryWithHelpers<
      HydratedDocument<TModelType>[],
      HydratedDocument<TModelType>,
      PopulateUserQuery<TModelType>
    >,
    field: string
  ) {
    return this.populate<{ [key in typeof field]: UserSummary }>({
      path: field,
      select: populatedFields,
    }) as QueryWithHelpers<
      HydratedDocument<TModelType>[],
      HydratedDocument<TModelType>,
      PopulateUserQuery<TModelType>
    >;
  };

  schema.method('populateUser', async function (this: Document<EnforcedDocType>, field: string) {
    return this.populate<{ [key in typeof field]: UserSummary }>({
      path: field,
      select: populatedFields,
    });
  });
}

I would appreciate any help.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.