Skip to content

Commit

Permalink
Replace Schema path generic TPathKey with TSchemaOptions to cover the…
Browse files Browse the repository at this point in the history
… entire schema optins one generic.
  • Loading branch information
mohammad0-0ahmad committed Jul 21, 2022
1 parent 0c92558 commit b5fccf6
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 27 deletions.
31 changes: 16 additions & 15 deletions test/types/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
SchemaType,
Query,
HydratedDocument,
SchemaOptions
SchemaOptions,
ObtainSchemaGeneric
} from 'mongoose';
import { expectType, expectError, expectAssignable } from 'tsd';

Expand Down Expand Up @@ -599,20 +600,6 @@ function gh11997() {
userSchema.index({ name: 1 }, { weights: { name: 1 } });
}

function gh12003() {
const baseSchemaOptions: SchemaOptions = {
versionKey: false
};

const BaseSchema = new Schema({
name: String
}, baseSchemaOptions);

type BaseSchemaType = InferSchemaType<typeof BaseSchema>;

expectType<{ name?: string }>({} as BaseSchemaType);
}

function gh11987() {
interface IUser {
name: string;
Expand Down Expand Up @@ -702,3 +689,17 @@ function gh12030() {
}>({} as InferSchemaType<typeof Schema6>);

}

function gh12122() {
const Test1 = new Schema({ test: String }, { typeKey: 'customTypeKey' });
expectType<{
typeKey: 'customTypeKey';
id: true;
}>({} as ObtainSchemaGeneric<typeof Test1, 'TSchemaOptions'>);

const Test2 = new Schema({ test: String }, {});
expectType<{
typeKey: 'type';
id: true;
}>({} as ObtainSchemaGeneric<typeof Test2, 'TSchemaOptions'>);
}
6 changes: 3 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ declare module 'mongoose' {

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

/** Adds key path / schema type pairs to this schema. */
add(obj: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>> | Schema, prefix?: string): this;
Expand Down
17 changes: 10 additions & 7 deletions types/inferschematype.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ declare module 'mongoose' {
* @param {EnforcedDocType} EnforcedDocType A generic type enforced by user "provided before schema constructor".
* @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition".
*/
type ObtainDocumentType<DocDefinition, EnforcedDocType = any, TypeKey extends TypeKeyBaseType = DefaultTypeKey> =
type ObtainDocumentType<DocDefinition, EnforcedDocType = any, TSchemaOptions extends Record<any, any> = DefaultSchemaOptions> =
IsItRecordAndNotAny<EnforcedDocType> extends true ? EnforcedDocType : {
[K in keyof (RequiredPaths<DocDefinition, TypeKey> &
OptionalPaths<DocDefinition, TypeKey>)]: ObtainDocumentPathType<DocDefinition[K], TypeKey>;
[K in keyof (RequiredPaths<DocDefinition, TSchemaOptions['typeKey']> &
OptionalPaths<DocDefinition, TSchemaOptions['typeKey']>)]: ObtainDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']>;
};

/**
Expand All @@ -45,21 +45,24 @@ declare module 'mongoose' {
* @param {TSchema} TSchema A generic of schema type instance.
* @param {alias} alias Targeted generic alias.
*/
type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TPathTypeKey' | 'DocType'> =
TSchema extends Schema<infer EnforcedDocType, infer M, infer TInstanceMethods, infer TQueryHelpers, infer TVirtuals, infer TStaticMethods, infer TPathTypeKey, infer DocType>
type ObtainSchemaGeneric<TSchema, alias extends 'EnforcedDocType' | 'M' | 'TInstanceMethods' | 'TQueryHelpers' | 'TVirtuals' | 'TStaticMethods' | 'TSchemaOptions' | 'DocType'> =
TSchema extends Schema<infer EnforcedDocType, infer M, infer TInstanceMethods, infer TQueryHelpers, infer TVirtuals, infer TStaticMethods, infer TSchemaOptions, infer DocType>
? {
EnforcedDocType: EnforcedDocType;
M: M;
TInstanceMethods: TInstanceMethods;
TQueryHelpers: TQueryHelpers;
TVirtuals: TVirtuals;
TStaticMethods: TStaticMethods;
TPathTypeKey: TPathTypeKey;
TSchemaOptions: TSchemaOptions;
DocType: DocType;
}[alias]
: unknown;

type ResolveSchemaOptions<T> = Omit<MergeType<DefaultSchemaOptions, T>, 'statics' | 'methods' | 'query' | 'virtuals'>;
}


/**
* @summary Checks if a document path is required or optional.
* @param {P} P Document path.
Expand Down Expand Up @@ -168,5 +171,5 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
IfEquals<PathValueType, {}> extends true ? any:
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, TypeKey> :
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, { typeKey: TypeKey }> :
unknown;
9 changes: 7 additions & 2 deletions types/schemaoptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ declare module 'mongoose' {
type TypeKeyBaseType = string;

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

/**
* By default, documents are automatically validated before they are saved to the database. This is to
Expand Down Expand Up @@ -214,4 +214,9 @@ declare module 'mongoose' {
*/
virtuals?: SchemaOptionsVirtualsPropertyType<DocType, TVirtuals, TInstanceMethods>,
}

interface DefaultSchemaOptions {
typeKey: 'type'
id: true
}
}

0 comments on commit b5fccf6

Please sign in to comment.