Skip to content

Commit 23b2512

Browse files
authored
Merge pull request #12042 from mohammad0-0ahmad-forks/_12030
Improve Auto typed schema.
2 parents 067ac13 + 9128dbd commit 23b2512

File tree

2 files changed

+100
-12
lines changed

2 files changed

+100
-12
lines changed

test/types/schema.test.ts

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ export function autoTypedSchema() {
429429
mixed3: Schema.Types.Mixed,
430430
objectId1: Schema.Types.ObjectId,
431431
objectId2: 'ObjectId',
432-
objectId3: 'objectId',
432+
objectId3: 'ObjectID',
433433
customSchema: Int8,
434434
map1: { type: Map, of: String },
435435
map2: { type: Map, of: Number },
@@ -540,7 +540,7 @@ export type AutoTypedSchemaType = {
540540
favoritDrink?: 'Tea' | 'Coffee',
541541
favoritColorMode: 'dark' | 'light'
542542
friendID?: Types.ObjectId;
543-
nestedArray: Array<{
543+
nestedArray: Types.DocumentArray<{
544544
date: Date;
545545
messages?: number;
546546
}>
@@ -630,3 +630,75 @@ function gh11987() {
630630
expectError(userSchema.path<'foo'>('name'));
631631
expectType<SchemaTypeOptions<string>>(userSchema.path<'name'>('name').OptionsConstructor);
632632
}
633+
634+
function gh12030() {
635+
const Schema1 = new Schema({
636+
users: [
637+
{
638+
username: { type: String }
639+
}
640+
]
641+
});
642+
643+
expectType<{
644+
users: {
645+
username?: string
646+
}[];
647+
}>({} as InferSchemaType<typeof Schema1>);
648+
649+
const Schema2 = new Schema({
650+
createdAt: { type: Date, default: Date.now }
651+
});
652+
653+
expectType<{ createdAt: Date }>({} as InferSchemaType<typeof Schema2>);
654+
655+
const Schema3 = new Schema({
656+
users: [
657+
new Schema({
658+
username: { type: String },
659+
credit: { type: Number, default: 0 }
660+
})
661+
]
662+
});
663+
664+
expectType<{
665+
users: Types.DocumentArray<{
666+
credit: number;
667+
username?: string;
668+
}>;
669+
}>({} as InferSchemaType<typeof Schema3>);
670+
671+
672+
const Schema4 = new Schema({
673+
data: { type: { role: String }, default: {} }
674+
});
675+
676+
expectType<{ data: { role?: string } }>({} as InferSchemaType<typeof Schema4>);
677+
678+
const Schema5 = new Schema({
679+
data: { type: { role: Object }, default: {} }
680+
});
681+
682+
expectType<{ data: { role?: any } }>({} as InferSchemaType<typeof Schema5>);
683+
684+
const Schema6 = new Schema({
685+
track: {
686+
backupCount: {
687+
type: Number,
688+
default: 0
689+
},
690+
count: {
691+
type: Number,
692+
default: 0
693+
}
694+
}
695+
});
696+
697+
expectType<{
698+
track?: {
699+
backupCount: number;
700+
count: number;
701+
};
702+
}>({} as InferSchemaType<typeof Schema6>);
703+
704+
}

types/inferschematype.d.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1-
import { Schema, InferSchemaType, SchemaType, SchemaTypeOptions, TypeKeyBaseType, Types, NumberSchemaDefinition, StringSchemaDefinition, BooleanSchemaDefinition, DateSchemaDefinition } from 'mongoose';
1+
import {
2+
Schema,
3+
InferSchemaType,
4+
SchemaType,
5+
SchemaTypeOptions,
6+
TypeKeyBaseType,
7+
Types,
8+
NumberSchemaDefinition,
9+
StringSchemaDefinition,
10+
BooleanSchemaDefinition,
11+
DateSchemaDefinition,
12+
ObtainDocumentType,
13+
DefaultTypeKey,
14+
ObjectIdSchemaDefinition
15+
} from 'mongoose';
216

317
declare module 'mongoose' {
418
/**
@@ -75,9 +89,9 @@ type IsPathRequired<P, TypeKey extends TypeKeyBaseType> =
7589
? P extends { default: undefined }
7690
? false
7791
: true
78-
: P extends (Record<TypeKey, NumberSchemaDefinition | StringSchemaDefinition | BooleanSchemaDefinition | DateSchemaDefinition>)
79-
? P extends { default: ResolvePathType<P[TypeKey]> }
80-
? true
92+
: P extends (Record<TypeKey, any>)
93+
? P extends { default: any }
94+
? IfEquals<P['default'], undefined, false, true>
8195
: false
8296
: false;
8397

@@ -138,7 +152,8 @@ type ObtainDocumentPathType<PathValueType, TypeKey extends TypeKeyBaseType> = Pa
138152
? InferSchemaType<PathValueType>
139153
: ResolvePathType<
140154
PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? PathValueType[TypeKey] : PathValueType,
141-
PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? Omit<PathValueType, TypeKey> : {}
155+
PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? Omit<PathValueType, TypeKey> : {},
156+
TypeKey
142157
>;
143158

144159
/**
@@ -151,23 +166,24 @@ type PathEnumOrString<T extends SchemaTypeOptions<string>['enum']> = T extends (
151166
* @summary Resolve path type by returning the corresponding type.
152167
* @param {PathValueType} PathValueType Document definition path type.
153168
* @param {Options} Options Document definition path options except path type.
154-
* @returns Number, "Number" or "number" will be resolved to string type.
169+
* @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition".
170+
* @returns Number, "Number" or "number" will be resolved to number type.
155171
*/
156-
type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueType> = {}> =
172+
type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueType> = {}, TypeKey extends TypeKeyBaseType = DefaultTypeKey> =
157173
PathValueType extends Schema ? InferSchemaType<PathValueType> :
158-
PathValueType extends (infer Item)[] ? IfEquals<Item, never, any, ResolvePathType<Item>>[] :
174+
PathValueType extends (infer Item)[] ? IfEquals<Item, never, any[], Item extends Schema ? Types.DocumentArray<ResolvePathType<Item>> : ResolvePathType<Item>[]> :
159175
PathValueType extends StringSchemaDefinition ? PathEnumOrString<Options['enum']> :
160176
PathValueType extends NumberSchemaDefinition ? number :
161177
PathValueType extends DateSchemaDefinition ? Date :
162178
PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
163179
PathValueType extends BooleanSchemaDefinition ? boolean :
164-
PathValueType extends 'objectId' | 'ObjectId' | typeof Schema.Types.ObjectId ? Types.ObjectId :
180+
PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId :
165181
PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 :
166182
PathValueType extends MapConstructor ? Map<string, ResolvePathType<Options['of']>> :
167183
PathValueType extends ArrayConstructor ? any[] :
168184
PathValueType extends typeof Schema.Types.Mixed ? any:
169185
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
170186
IfEquals<PathValueType, {}> extends true ? any:
171187
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
172-
PathValueType extends {} ? PathValueType :
188+
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, TypeKey> :
173189
unknown;

0 commit comments

Comments
 (0)