Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript docs: query helpers, statics #10021

Closed
UncleVic opened this issue Mar 12, 2021 · 4 comments
Closed

TypeScript docs: query helpers, statics #10021

UncleVic opened this issue Mar 12, 2021 · 4 comments
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@UncleVic
Copy link

UncleVic commented Mar 12, 2021

Hi there,

I've tried migrate to v.12 and have some questions.

How can I type populate?
May be I don't understand, but I couldn't set type in Model for populate query.

Can I have strong types for static methods?
Now I can see that any static method has type (...args: any[])

How can I use TQueryHelpers?

Thanks

@IslandRhythms IslandRhythms added help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary typescript Types or Types-test related issue / Pull Request labels Mar 16, 2021
@vkarpov15
Copy link
Collaborator

@UncleVic :

  1. Can you please clarify what you mean by "type populate" and "set type in Model for populate query"?

  2. No, I think we'll need to add another generic parameter to the Model interface for this.

  3. Here's an example in our tests. We don't currently have very good docs for TypeScript.

@vkarpov15 vkarpov15 changed the title Typescript Model Strongly typed statics for models Mar 19, 2021
@vkarpov15 vkarpov15 added this to the 5.12.2 milestone Mar 19, 2021
@vkarpov15
Copy link
Collaborator

I took a closer look and for (2) we don't need another generic parameter. Just define a new interface that extends Model and includes the statics you want:

interface IProject extends Document {
  name: string;
}

interface ProjectModel extends Model<IProject> {
  myStatic(n: number): number;
}

const Project = connection.model<IProject, ProjectModel, {}>('Project', projectSchema);
// `Project` gets `myStatic()` from `ProjectModel`
Project.myStatic(42);

@vkarpov15 vkarpov15 added docs This issue is due to a mistake or omission in the mongoosejs.com documentation typescript Types or Types-test related issue / Pull Request and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary typescript Types or Types-test related issue / Pull Request labels Mar 20, 2021
@vkarpov15 vkarpov15 changed the title Strongly typed statics for models TypeScript docs: query helpers, statics Mar 20, 2021
@UncleVic
Copy link
Author

I have a type:

interface IProject {
  users: Schema.Types.ObjectId[] | IUser[];
}

interface IProjectDocument extends IProject, Document {
  users: IUser[]; 
}

interface IProjectPopulatedDocument extends IProject, Document {
  users: Schema.Types.ObjectId[]; 
}

With a usual query, I have ObjectIds array in field users
When I do populate I should have array of IUser.
For example,

const project =  Project.findById('id'); // project: IProjectDocument
await project.populate('users);  // project: IProjectPopulatedDocument

@jacobmolby
Copy link

The way I've solved it is to always populate through a function, then you can cast the the return type to the correct types.
I have for the different scenarios I want to populate as an example.

/**
 *  Takes a listing query, executes it and populates the listing
 * @param listingQuery a mongoose listing query
 */
export const populateListings = async (
  listingQuery: Query<IListing[], IListing>
): Promise<IListing_populated[]> => {
  return (await listingQuery.populate({
    path: 'bids.user owner comments.user comments.answers.user',
    select: 'fullName profilePicture',
  })) as IListing_populated[];
};


/**
 *  Takes a listing query, executes it and populates the listing
 * @param listingQuery a mongoose listing query
 */
export const populateListing = async (
  listingQuery: Query<IListing | null, IListing>
): Promise<IListing_populated | null> => {
  return (await listingQuery.populate({
    path: 'bids.user owner comments.user comments.answers.user',
    select: 'fullName profilePicture',
  })) as IListing_populated;
};


export const populateListingDocument = async (
  listing: IListing
): Promise<IListing_populated> => {
  return (await listing
    .populate({
      path: 'bids.user owner comments.user comments.answers.user',
      select: 'fullName profilePicture',
    })
    .execPopulate()) as IListing_populated;
};

Then it can be consumed like this:

const listing = await populateListing(Listing.findById(listingId));

Where listing is now of type IListing_populated

It can probably be done smarter, but at least this solves it for now

@vkarpov15 vkarpov15 modified the milestones: 5.12.2, 5.12.3 Mar 22, 2021
@vkarpov15 vkarpov15 modified the milestones: 5.12.3, 5.12.4 Mar 31, 2021
@vkarpov15 vkarpov15 modified the milestones: 5.12.4, 5.12.5, 5.12.6 Apr 15, 2021
@vkarpov15 vkarpov15 modified the milestones: 5.12.6, 5.12.7, 5.12.8 Apr 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

No branches or pull requests

4 participants