Skip to content

Commit b5fccf6

Browse files
Replace Schema path generic TPathKey with TSchemaOptions to cover the entire schema optins one generic.
1 parent 0c92558 commit b5fccf6

File tree

4 files changed

+36
-27
lines changed

4 files changed

+36
-27
lines changed

test/types/schema.test.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
SchemaType,
1010
Query,
1111
HydratedDocument,
12-
SchemaOptions
12+
SchemaOptions,
13+
ObtainSchemaGeneric
1314
} from 'mongoose';
1415
import { expectType, expectError, expectAssignable } from 'tsd';
1516

@@ -599,20 +600,6 @@ function gh11997() {
599600
userSchema.index({ name: 1 }, { weights: { name: 1 } });
600601
}
601602

602-
function gh12003() {
603-
const baseSchemaOptions: SchemaOptions = {
604-
versionKey: false
605-
};
606-
607-
const BaseSchema = new Schema({
608-
name: String
609-
}, baseSchemaOptions);
610-
611-
type BaseSchemaType = InferSchemaType<typeof BaseSchema>;
612-
613-
expectType<{ name?: string }>({} as BaseSchemaType);
614-
}
615-
616603
function gh11987() {
617604
interface IUser {
618605
name: string;
@@ -702,3 +689,17 @@ function gh12030() {
702689
}>({} as InferSchemaType<typeof Schema6>);
703690

704691
}
692+
693+
function gh12122() {
694+
const Test1 = new Schema({ test: String }, { typeKey: 'customTypeKey' });
695+
expectType<{
696+
typeKey: 'customTypeKey';
697+
id: true;
698+
}>({} as ObtainSchemaGeneric<typeof Test1, 'TSchemaOptions'>);
699+
700+
const Test2 = new Schema({ test: String }, {});
701+
expectType<{
702+
typeKey: 'type';
703+
id: true;
704+
}>({} as ObtainSchemaGeneric<typeof Test2, 'TSchemaOptions'>);
705+
}

types/index.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,13 @@ declare module 'mongoose' {
159159

160160
export class Schema<EnforcedDocType = any, M = Model<EnforcedDocType, any, any, any>, TInstanceMethods = {}, TQueryHelpers = {}, TVirtuals = {},
161161
TStaticMethods = {},
162-
TPathTypeKey extends TypeKeyBaseType = DefaultTypeKey,
163-
DocType extends ObtainDocumentType<DocType, EnforcedDocType, TPathTypeKey> = ObtainDocumentType<any, EnforcedDocType, TPathTypeKey>>
162+
TSchemaOptions extends ResolveSchemaOptions<TSchemaOptions> = DefaultSchemaOptions,
163+
DocType extends ObtainDocumentType<DocType, EnforcedDocType, TSchemaOptions> = ObtainDocumentType<any, EnforcedDocType, TSchemaOptions>>
164164
extends events.EventEmitter {
165165
/**
166166
* Create a new schema
167167
*/
168-
constructor(definition?: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>> | DocType, options?: SchemaOptions<TPathTypeKey, FlatRecord<DocType>, TInstanceMethods, TQueryHelpers, TStaticMethods, TVirtuals>);
168+
constructor(definition?: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>> | DocType, options?: SchemaOptions<FlatRecord<DocType>, TInstanceMethods, TQueryHelpers, TStaticMethods, TVirtuals> | TSchemaOptions);
169169

170170
/** Adds key path / schema type pairs to this schema. */
171171
add(obj: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>> | Schema, prefix?: string): this;

types/inferschematype.d.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ declare module 'mongoose' {
2323
* @param {EnforcedDocType} EnforcedDocType A generic type enforced by user "provided before schema constructor".
2424
* @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition".
2525
*/
26-
type ObtainDocumentType<DocDefinition, EnforcedDocType = any, TypeKey extends TypeKeyBaseType = DefaultTypeKey> =
26+
type ObtainDocumentType<DocDefinition, EnforcedDocType = any, TSchemaOptions extends Record<any, any> = DefaultSchemaOptions> =
2727
IsItRecordAndNotAny<EnforcedDocType> extends true ? EnforcedDocType : {
28-
[K in keyof (RequiredPaths<DocDefinition, TypeKey> &
29-
OptionalPaths<DocDefinition, TypeKey>)]: ObtainDocumentPathType<DocDefinition[K], TypeKey>;
28+
[K in keyof (RequiredPaths<DocDefinition, TSchemaOptions['typeKey']> &
29+
OptionalPaths<DocDefinition, TSchemaOptions['typeKey']>)]: ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']>;
3030
};
3131

3232
/**
@@ -45,21 +45,24 @@ declare module 'mongoose' {
4545
* @param {TSchema} TSchema A generic of schema type instance.
4646
* @param {alias} alias Targeted generic alias.
4747
*/
48-
type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TPathTypeKey' | 'DocType'> =
49-
TSchema extends Schema<infer EnforcedDocType, infer M, infer TInstanceMethods, infer TQueryHelpers, infer TVirtuals, infer TStaticMethods, infer TPathTypeKey, infer DocType>
48+
type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TSchemaOptions' | 'DocType'> =
49+
TSchema extends Schema<infer EnforcedDocType, infer M, infer TInstanceMethods, infer TQueryHelpers, infer TVirtuals, infer TStaticMethods, infer TSchemaOptions, infer DocType>
5050
? {
5151
EnforcedDocType: EnforcedDocType;
5252
M: M;
5353
TInstanceMethods: TInstanceMethods;
5454
TQueryHelpers: TQueryHelpers;
5555
TVirtuals: TVirtuals;
5656
TStaticMethods: TStaticMethods;
57-
TPathTypeKey: TPathTypeKey;
57+
TSchemaOptions: TSchemaOptions;
5858
DocType: DocType;
5959
}[alias]
6060
: unknown;
61+
62+
type ResolveSchemaOptions<T> = Omit<MergeType<DefaultSchemaOptions, T>, 'statics' | 'methods' | 'query' | 'virtuals'>;
6163
}
6264

65+
6366
/**
6467
* @summary Checks if a document path is required or optional.
6568
* @param {P} P Document path.
@@ -168,5 +171,5 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
168171
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
169172
IfEquals<PathValueType, {}> extends true ? any:
170173
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
171-
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, TypeKey> :
174+
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, { typeKey: TypeKey }> :
172175
unknown;

types/schemaoptions.d.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare module 'mongoose' {
1010
type TypeKeyBaseType = string;
1111

1212
type DefaultTypeKey = 'type';
13-
interface SchemaOptions<PathTypeKey extends TypeKeyBaseType = DefaultTypeKey, DocType = unknown, TInstanceMethods = {}, QueryHelpers = {}, TStaticMethods = {}, TVirtuals = {}> {
13+
interface SchemaOptions<DocType = unknown, TInstanceMethods = {}, QueryHelpers = {}, TStaticMethods = {}, TVirtuals = {}> {
1414
/**
1515
* By default, Mongoose's init() function creates all the indexes defined in your model's schema by
1616
* calling Model.createIndexes() after you successfully connect to MongoDB. If you want to disable
@@ -139,7 +139,7 @@ declare module 'mongoose' {
139139
* type declaration. However, for applications like geoJSON, the 'type' property is important. If you want to
140140
* control which key mongoose uses to find type declarations, set the 'typeKey' schema option.
141141
*/
142-
typeKey?: PathTypeKey;
142+
typeKey?: TypeKeyBaseType;
143143

144144
/**
145145
* By default, documents are automatically validated before they are saved to the database. This is to
@@ -214,4 +214,9 @@ declare module 'mongoose' {
214214
*/
215215
virtuals?: SchemaOptionsVirtualsPropertyType<DocType, TVirtuals, TInstanceMethods>,
216216
}
217+
218+
interface DefaultSchemaOptions {
219+
typeKey: 'type'
220+
id: true
221+
}
217222
}

0 commit comments

Comments
 (0)