Skip to content

Commit e1d4aa4

Browse files
committedSep 1, 2021
fix(index.d.ts): simplify UpdateQuery to avoid "excessively deep and possibly infinite" errors with extends Document and any
Fix #10617
1 parent 3ee32b1 commit e1d4aa4

File tree

3 files changed

+32
-72
lines changed

3 files changed

+32
-72
lines changed
 

‎index.d.ts

+15-70
Original file line numberDiff line numberDiff line change
@@ -2561,87 +2561,32 @@ declare module 'mongoose' {
25612561
$sort?: SortValues | Record<string, SortValues>;
25622562
};
25632563

2564-
type SetFields<TSchema> = ({
2565-
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any> | undefined>]?:
2566-
| Unpacked<TSchema[key]>
2567-
| AddToSetOperators<Unpacked<TSchema[key]>[]>;
2568-
} &
2569-
NotAcceptedFields<TSchema, ReadonlyArray<any> | undefined>) & {
2570-
readonly [key: string]: AddToSetOperators<any> | any;
2571-
};
2572-
2573-
type PushOperator<TSchema> = ({
2574-
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any>>]?:
2575-
| Unpacked<TSchema[key]>
2576-
| ArrayOperator<Unpacked<TSchema[key]>[]>;
2577-
} &
2578-
NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
2579-
readonly [key: string]: ArrayOperator<any> | any;
2580-
};
2581-
25822564
type ObjectQuerySelector<T> = T extends object ? { [key in keyof T]?: QuerySelector<T[key]> } : QuerySelector<T>;
25832565

2584-
type PullOperator<TSchema> = {
2585-
[key in KeysOfAType<TSchema, ReadonlyArray<any>>]?:
2586-
| Partial<Unpacked<TSchema[key]>>
2587-
| ObjectQuerySelector<Unpacked<TSchema[key]>>
2588-
// Doesn't look like TypeScript has good support for creating an
2589-
// object containing dotted keys:
2590-
// https://stackoverflow.com/questions/58434389/typescript-deep-keyof-of-a-nested-object
2591-
| any;
2592-
} | any; // Because TS doesn't have good support for creating an object with dotted keys, including `.$.` re: #10075
2593-
2594-
type PullAllOperator<TSchema> = ({
2595-
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any>>]?: TSchema[key];
2596-
} &
2597-
NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
2598-
readonly [key: string]: any[];
2566+
type OnlyFieldsOfType<TSchema, FieldType = any, AssignableType = FieldType> = {
2567+
[key in keyof TSchema]?: [Extract<TSchema[key], FieldType>] extends [never] ? never : AssignableType;
25992568
};
26002569

2601-
type KeysOfAType<TSchema, Type> = {
2602-
[key in keyof TSchema]: NonNullable<TSchema[key]> extends Type ? key : never;
2603-
}[keyof TSchema];
2604-
type KeysOfOtherType<TSchema, Type> = {
2605-
[key in keyof TSchema]: NonNullable<TSchema[key]> extends Type ? never : key;
2606-
}[keyof TSchema];
2607-
2608-
type AcceptedFields<TSchema, FieldType, AssignableType> = {
2609-
readonly [key in KeysOfAType<TSchema, FieldType>]?: AssignableType;
2610-
};
2611-
2612-
/** It avoid uses fields of non Type */
2613-
type NotAcceptedFields<TSchema, FieldType> = {
2614-
readonly [key in KeysOfOtherType<TSchema, FieldType>]?: never;
2615-
};
2616-
2617-
type OnlyFieldsOfType<TSchema, FieldType = any, AssignableType = FieldType> = AcceptedFields<
2618-
TSchema,
2619-
FieldType,
2620-
AssignableType
2621-
> &
2622-
NotAcceptedFields<TSchema, FieldType> &
2623-
DotAndArrayNotation<AssignableType>;
2624-
26252570
type NumericTypes = number | Decimal128 | mongodb.Double | mongodb.Int32 | mongodb.Long;
26262571

26272572
type _UpdateQuery<TSchema> = {
26282573
/** @see https://docs.mongodb.com/manual/reference/operator/update-field/ */
2629-
$currentDate?: OnlyFieldsOfType<TSchema, NativeDate, true | { $type: 'date' | 'timestamp' }>;
2630-
$inc?: OnlyFieldsOfType<TSchema, NumericTypes | undefined>;
2631-
$min?: MatchKeysAndValues<TSchema>;
2632-
$max?: MatchKeysAndValues<TSchema>;
2633-
$mul?: OnlyFieldsOfType<TSchema, NumericTypes | undefined>;
2574+
$currentDate?: OnlyFieldsOfType<TSchema, NativeDate, true | { $type: 'date' | 'timestamp' }> & AnyObject;
2575+
$inc?: OnlyFieldsOfType<TSchema, NumericTypes | undefined> & AnyObject;
2576+
$min?: OnlyFieldsOfType<TSchema, any, any> & AnyObject;
2577+
$max?: OnlyFieldsOfType<TSchema, any, any> & AnyObject;
2578+
$mul?: OnlyFieldsOfType<TSchema, NumericTypes | undefined> & AnyObject;
26342579
$rename?: { [key: string]: string };
2635-
$set?: MatchKeysAndValues<TSchema>;
2636-
$setOnInsert?: MatchKeysAndValues<TSchema>;
2637-
$unset?: OnlyFieldsOfType<TSchema, any, any>;
2580+
$set?: OnlyFieldsOfType<TSchema, any, any> & AnyObject;
2581+
$setOnInsert?: OnlyFieldsOfType<TSchema, any, any> & AnyObject;
2582+
$unset?: OnlyFieldsOfType<TSchema, any, any> & AnyObject;
26382583

26392584
/** @see https://docs.mongodb.com/manual/reference/operator/update-array/ */
2640-
$addToSet?: SetFields<TSchema>;
2641-
$pop?: OnlyFieldsOfType<TSchema, ReadonlyArray<any>, 1 | -1>;
2642-
$pull?: PullOperator<TSchema>;
2643-
$push?: PushOperator<TSchema>;
2644-
$pullAll?: PullAllOperator<TSchema>;
2585+
$addToSet?: OnlyFieldsOfType<TSchema, any[], any> & AnyObject;
2586+
$pop?: OnlyFieldsOfType<TSchema, ReadonlyArray<any>, 1 | -1> & AnyObject;
2587+
$pull?: OnlyFieldsOfType<TSchema, ReadonlyArray<any>, any> & AnyObject;
2588+
$push?: OnlyFieldsOfType<TSchema, ReadonlyArray<any>, any> & AnyObject;
2589+
$pullAll?: OnlyFieldsOfType<TSchema, ReadonlyArray<any>, any> & AnyObject;
26452590

26462591
/** @see https://docs.mongodb.com/manual/reference/operator/update-bitwise/ */
26472592
$bit?: {

‎test/typescript/queries.ts

+15
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,19 @@ function eachAsync(): void {
127127
Test.find().cursor().eachAsync((doc: ITest) => console.log(doc.name));
128128

129129
Test.find().cursor().eachAsync((docs: ITest[]) => console.log(docs[0].name), { batchSize: 2 });
130+
}
131+
132+
async function gh10617(): Promise<void> {
133+
interface IDBModel extends Document {
134+
date: Date; // date created
135+
_tags: any[];
136+
}
137+
138+
const schema = new Schema({
139+
date: { type: Date, default: Date.now }, // date created
140+
_tags: [{ type: Schema.Types.ObjectId, ref: 'Tag' }]
141+
});
142+
143+
const DBModel: Model<IDBModel> = model<IDBModel>('Meep', schema);
144+
await DBModel.findOne({});
130145
}

‎test/typescript/virtuals.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ petSchema.virtual('owner', {
5151
}
5252
});
5353

54-
const Person = model('Person', personSchema);
55-
const Pet = model('Pet', petSchema);
54+
const Person = model<IPerson>('Person', personSchema);
55+
const Pet = model<IPet>('Pet', petSchema);
5656

5757
(async() => {
5858
const person = await Person.create({ _id: 1, firstName: 'John', lastName: 'Wick' });

0 commit comments

Comments
 (0)
Please sign in to comment.