Skip to content

Commit

Permalink
Merge pull request #13066 from Automattic/vkarpov15/gh-13040
Browse files Browse the repository at this point in the history
fix(types): use MergeTypes for type overrides in HydratedDocument
  • Loading branch information
vkarpov15 committed Feb 21, 2023
2 parents 67f0489 + 170d8fc commit ce2061e
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"@babel/preset-env": "7.20.2",
"@typescript-eslint/eslint-plugin": "5.50.0",
"@typescript-eslint/parser": "5.50.0",
"acquit": "1.2.1",
"acquit-ignore": "0.2.0",
"acquit": "1.3.0",
"acquit-ignore": "0.2.1",
"acquit-require": "0.1.1",
"assert-browserify": "2.0.0",
"axios": "1.1.3",
Expand Down
2 changes: 2 additions & 0 deletions test/types/.eslintrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rules:
"@typescript-eslint/no-empty-interface": off
2 changes: 1 addition & 1 deletion test/types/lean.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ async function getBaseDocumentTypeFromModel(): Promise<void> {

type baseFromUserDocType = BaseDocumentType<UserDocType>;

expectType<User & { _id: Types.ObjectId }>({} as baseFromUserDocType);
expectType<Omit<User & { _id: Types.ObjectId }, never>>({} as baseFromUserDocType);

const a: UserDocType = {} as any;

Expand Down
32 changes: 32 additions & 0 deletions test/types/subdocuments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,35 @@ function gh10674() {
async function gh10947(): Promise<void> {
await Test.findOneAndUpdate({}, { child1: { name: 'foo' } });
}

function gh13040(): void {
interface Product {}

interface User {
products: Product[];
}

// I want my `UserDocument` type to define `products` as a `DocumentArray`; I'll do this using overrides

interface UserOverrides {
products: Types.DocumentArray<Product>;
}

type UserModel = Model<User, {}, UserOverrides>;

// Here I determine the type of user documents; I could also manually define a `HydratedDocument` - makes no difference.

type UserDocument = InstanceType<UserModel>;

// Assume I have an instance of `UserDocument`

let user!: UserDocument;

// This is then fine:

user.products[0].ownerDocument(); // ok

user.products.forEach(product => {
product.ownerDocument();
});
}
8 changes: 5 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@ declare module 'mongoose' {
? IfAny<U, T & { _id: Types.ObjectId }, T & Required<{ _id: U }>>
: T & { _id: Types.ObjectId };

export type HydratedDocument<DocType, TMethodsAndOverrides = {}, TVirtuals = {}> = DocType extends Document ? Require_id<DocType> : (Document<unknown, any, DocType> & Require_id<DocType> & TVirtuals & TMethodsAndOverrides);
export type HydratedDocument<DocType, TMethodsAndOverrides = {}, TVirtuals = {}> = DocType extends Document ?
Require_id<DocType> :
Document<unknown, any, DocType> & MergeType<Require_id<DocType>, TVirtuals & TMethodsAndOverrides>;

export type HydratedDocumentFromSchema<TSchema extends Schema> = HydratedDocument<
InferSchemaType<TSchema>,
ObtainSchemaGeneric<TSchema, 'TQueryHelpers'>,
ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>
ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>,
ObtainSchemaGeneric<TSchema, 'TVirtuals'>
>;

export interface TagSet {
Expand Down

0 comments on commit ce2061e

Please sign in to comment.