Skip to content

Commit

Permalink
Merge pull request #11848 from Uzlopak/fix-schematypeoptions
Browse files Browse the repository at this point in the history
fix: typings of schemaTypeOptions should be a class
  • Loading branch information
Uzlopak authored May 28, 2022
2 parents ec4c2c6 + 1fafd09 commit 996e48d
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 142 deletions.
33 changes: 33 additions & 0 deletions test/types/schemaTypeOptions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
AnyArray,
Schema,
SchemaDefinition,
SchemaType,
SchemaTypeOptions,
Types,
ObjectId,
Unpacked,

BooleanSchemaDefinition,
DateSchemaDefinition,
NumberSchemaDefinition,
ObjectIdSchemaDefinition,
StringSchemaDefinition
} from 'mongoose';
import { expectType } from 'tsd';

(new SchemaTypeOptions<boolean>()) instanceof SchemaTypeOptions;

expectType<BooleanSchemaDefinition | undefined>(new SchemaTypeOptions<boolean>().type);
expectType<NumberSchemaDefinition | undefined>(new SchemaTypeOptions<number>().type);
expectType<DateSchemaDefinition | undefined>(new SchemaTypeOptions<Date>().type);
expectType<StringSchemaDefinition | undefined>(new SchemaTypeOptions<string>().type);
expectType<SchemaDefinition<typeof Map> | undefined>(new SchemaTypeOptions<Map<any, any>>().type);
expectType<SchemaDefinition<typeof Buffer> | undefined>(new SchemaTypeOptions<Buffer>().type);
expectType<ObjectIdSchemaDefinition | undefined>(new SchemaTypeOptions<Types.ObjectId>().type);
expectType<AnyArray<ObjectIdSchemaDefinition> | AnyArray<SchemaTypeOptions<ObjectId>> | undefined>(new SchemaTypeOptions<Types.ObjectId[]>().type);
expectType<(AnyArray<Schema<any, any, any>> | AnyArray<SchemaDefinition<Unpacked<object[]>>> | AnyArray<SchemaTypeOptions<Unpacked<object[]>>>) | undefined>(new SchemaTypeOptions<object[]>().type);
expectType<AnyArray<StringSchemaDefinition> | AnyArray<SchemaTypeOptions<string>> | undefined>(new SchemaTypeOptions<string[]>().type);
expectType<AnyArray<NumberSchemaDefinition> | AnyArray<SchemaTypeOptions<number>> | undefined>(new SchemaTypeOptions<number[]>().type);
expectType<AnyArray<BooleanSchemaDefinition> | AnyArray<SchemaTypeOptions<boolean>> | undefined>(new SchemaTypeOptions<boolean[]>().type);
expectType<(Function | typeof SchemaType | Schema<any, any, any> | SchemaDefinition<Function> | Function | AnyArray<Function>) | undefined>(new SchemaTypeOptions<Function>().type);
143 changes: 1 addition & 142 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// <reference path="./mongooseoptions.d.ts" />
/// <reference path="./pipelinestage.d.ts" />
/// <reference path="./schemaoptions.d.ts" />
/// <reference path="./schematypeoptions.d.ts" />

declare class NativeDate extends global.Date { }

Expand Down Expand Up @@ -1032,148 +1033,6 @@ declare module 'mongoose' {
type: typeof Schema.Types.Mixed;
}

export interface SchemaTypeOptions<T> {
type?:
T extends string ? StringSchemaDefinition :
T extends number ? NumberSchemaDefinition :
T extends boolean ? BooleanSchemaDefinition :
T extends NativeDate ? DateSchemaDefinition :
T extends Map<any, any> ? SchemaDefinition<typeof Map> :
T extends Buffer ? SchemaDefinition<typeof Buffer> :
T extends Types.ObjectId ? ObjectIdSchemaDefinition :
T extends Types.ObjectId[] ? AnyArray<ObjectIdSchemaDefinition> | AnyArray<SchemaTypeOptions<ObjectId>> :
T extends object[] ? (AnyArray<Schema<any, any, any>> | AnyArray<SchemaDefinition<Unpacked<T>>> | AnyArray<SchemaTypeOptions<Unpacked<T>>>) :
T extends string[] ? AnyArray<StringSchemaDefinition> | AnyArray<SchemaTypeOptions<string>> :
T extends number[] ? AnyArray<NumberSchemaDefinition> | AnyArray<SchemaTypeOptions<number>> :
T extends boolean[] ? AnyArray<BooleanSchemaDefinition> | AnyArray<SchemaTypeOptions<boolean>> :
T extends Function[] ? AnyArray<Function | string> | AnyArray<SchemaTypeOptions<Unpacked<T>>> :
T | typeof SchemaType | Schema<any, any, any> | SchemaDefinition<T> | Function | AnyArray<Function>;

/** Defines a virtual with the given name that gets/sets this path. */
alias?: string;

/** Function or object describing how to validate this schematype. See [validation docs](https://mongoosejs.com/docs/validation.html). */
validate?: SchemaValidator<T> | AnyArray<SchemaValidator<T>>;

/** Allows overriding casting logic for this individual path. If a string, the given string overwrites Mongoose's default cast error message. */
cast?: string;

/**
* If true, attach a required validator to this path, which ensures this path
* path cannot be set to a nullish value. If a function, Mongoose calls the
* function and only checks for nullish values if the function returns a truthy value.
*/
required?: boolean | (() => boolean) | [boolean, string] | [() => boolean, string];

/**
* The default value for this path. If a function, Mongoose executes the function
* and uses the return value as the default.
*/
default?: T extends Schema.Types.Mixed ? ({} | ((this: any, doc: any) => any)) : (ExtractMongooseArray<T> | ((this: any, doc: any) => Partial<ExtractMongooseArray<T>>));

/**
* The model that `populate()` should use if populating this path.
*/
ref?: string | Model<any> | ((this: any, doc: any) => string | Model<any>);

/**
* Whether to include or exclude this path by default when loading documents
* using `find()`, `findOne()`, etc.
*/
select?: boolean | number;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* build an index on this path when the model is compiled.
*/
index?: boolean | number | IndexOptions | '2d' | '2dsphere' | 'hashed' | 'text';

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose
* will build a unique index on this path when the
* model is compiled. [The `unique` option is **not** a validator](/docs/validation.html#the-unique-option-is-not-a-validator).
*/
unique?: boolean | number;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* disallow changes to this path once the document is saved to the database for the first time. Read more
* about [immutability in Mongoose here](http://thecodebarbarian.com/whats-new-in-mongoose-5-6-immutable-properties.html).
*/
immutable?: boolean | ((this: any, doc: any) => boolean);

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* build a sparse index on this path.
*/
sparse?: boolean | number;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose
* will build a text index on this path.
*/
text?: boolean | number | any;

/**
* Define a transform function for this individual schema type.
* Only called when calling `toJSON()` or `toObject()`.
*/
transform?: (this: any, val: T) => any;

/** defines a custom getter for this property using [`Object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). */
get?: (value: any, doc?: this) => T;

/** defines a custom setter for this property using [`Object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). */
set?: (value: any, priorVal?: T, doc?: this) => any;

/** array of allowed values for this path. Allowed for strings, numbers, and arrays of strings */
enum?: Array<string | number | null> | ReadonlyArray<string | number | null> | { values: Array<string | number | null> | ReadonlyArray<string | number | null>, message?: string } | { [path: string]: string | number | null };

/** The default [subtype](http://bsonspec.org/spec.html) associated with this buffer when it is stored in MongoDB. Only allowed for buffer paths */
subtype?: number;

/** The minimum value allowed for this path. Only allowed for numbers and dates. */
min?: number | NativeDate | [number, string] | [NativeDate, string] | readonly [number, string] | readonly [NativeDate, string];

/** The maximum value allowed for this path. Only allowed for numbers and dates. */
max?: number | NativeDate | [number, string] | [NativeDate, string] | readonly [number, string] | readonly [NativeDate, string];

/** Defines a TTL index on this path. Only allowed for dates. */
expires?: string | number;

/** If `true`, Mongoose will skip gathering indexes on subpaths. Only allowed for subdocuments and subdocument arrays. */
excludeIndexes?: boolean;

/** If set, overrides the child schema's `_id` option. Only allowed for subdocuments and subdocument arrays. */
_id?: boolean;

/** If set, specifies the type of this map's values. Mongoose will cast this map's values to the given type. */
of?: Function | SchemaDefinitionProperty<any>;

/** If true, uses Mongoose's default `_id` settings. Only allowed for ObjectIds */
auto?: boolean;

/** Attaches a validator that succeeds if the data string matches the given regular expression, and fails otherwise. */
match?: RegExp | [RegExp, string] | readonly [RegExp, string];

/** If truthy, Mongoose will add a custom setter that lowercases this string using JavaScript's built-in `String#toLowerCase()`. */
lowercase?: boolean;

/** If truthy, Mongoose will add a custom setter that removes leading and trailing whitespace using JavaScript's built-in `String#trim()`. */
trim?: boolean;

/** If truthy, Mongoose will add a custom setter that uppercases this string using JavaScript's built-in `String#toUpperCase()`. */
uppercase?: boolean;

/** If set, Mongoose will add a custom validator that ensures the given string's `length` is at least the given number. */
minlength?: number | [number, string] | readonly [number, string];

/** If set, Mongoose will add a custom validator that ensures the given string's `length` is at most the given number. */
maxlength?: number | [number, string] | readonly [number, string];

[other: string]: any;
}

export type RefType =
| number
| string
Expand Down
144 changes: 144 additions & 0 deletions types/schematypeoptions.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
declare module 'mongoose' {

export class SchemaTypeOptions<T> {
type?:
T extends string ? StringSchemaDefinition :
T extends number ? NumberSchemaDefinition :
T extends boolean ? BooleanSchemaDefinition :
T extends NativeDate ? DateSchemaDefinition :
T extends Map<any, any> ? SchemaDefinition<typeof Map> :
T extends Buffer ? SchemaDefinition<typeof Buffer> :
T extends Types.ObjectId ? ObjectIdSchemaDefinition :
T extends Types.ObjectId[] ? AnyArray<ObjectIdSchemaDefinition> | AnyArray<SchemaTypeOptions<ObjectId>> :
T extends object[] ? (AnyArray<Schema<any, any, any>> | AnyArray<SchemaDefinition<Unpacked<T>>> | AnyArray<SchemaTypeOptions<Unpacked<T>>>) :
T extends string[] ? AnyArray<StringSchemaDefinition> | AnyArray<SchemaTypeOptions<string>> :
T extends number[] ? AnyArray<NumberSchemaDefinition> | AnyArray<SchemaTypeOptions<number>> :
T extends boolean[] ? AnyArray<BooleanSchemaDefinition> | AnyArray<SchemaTypeOptions<boolean>> :
T extends Function[] ? AnyArray<Function | string> | AnyArray<SchemaTypeOptions<Unpacked<T>>> :
T | typeof SchemaType | Schema<any, any, any> | SchemaDefinition<T> | Function | AnyArray<Function>;

/** Defines a virtual with the given name that gets/sets this path. */
alias?: string;

/** Function or object describing how to validate this schematype. See [validation docs](https://mongoosejs.com/docs/validation.html). */
validate?: SchemaValidator<T> | AnyArray<SchemaValidator<T>>;

/** Allows overriding casting logic for this individual path. If a string, the given string overwrites Mongoose's default cast error message. */
cast?: string;

/**
* If true, attach a required validator to this path, which ensures this path
* path cannot be set to a nullish value. If a function, Mongoose calls the
* function and only checks for nullish values if the function returns a truthy value.
*/
required?: boolean | (() => boolean) | [boolean, string] | [() => boolean, string];

/**
* The default value for this path. If a function, Mongoose executes the function
* and uses the return value as the default.
*/
default?: T extends Schema.Types.Mixed ? ({} | ((this: any, doc: any) => any)) : (ExtractMongooseArray<T> | ((this: any, doc: any) => Partial<ExtractMongooseArray<T>>));

/**
* The model that `populate()` should use if populating this path.
*/
ref?: string | Model<any> | ((this: any, doc: any) => string | Model<any>);

/**
* Whether to include or exclude this path by default when loading documents
* using `find()`, `findOne()`, etc.
*/
select?: boolean | number;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* build an index on this path when the model is compiled.
*/
index?: boolean | number | IndexOptions | '2d' | '2dsphere' | 'hashed' | 'text';

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose
* will build a unique index on this path when the
* model is compiled. [The `unique` option is **not** a validator](/docs/validation.html#the-unique-option-is-not-a-validator).
*/
unique?: boolean | number;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* disallow changes to this path once the document is saved to the database for the first time. Read more
* about [immutability in Mongoose here](http://thecodebarbarian.com/whats-new-in-mongoose-5-6-immutable-properties.html).
*/
immutable?: boolean | ((this: any, doc: any) => boolean);

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* build a sparse index on this path.
*/
sparse?: boolean | number;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose
* will build a text index on this path.
*/
text?: boolean | number | any;

/**
* Define a transform function for this individual schema type.
* Only called when calling `toJSON()` or `toObject()`.
*/
transform?: (this: any, val: T) => any;

/** defines a custom getter for this property using [`Object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). */
get?: (value: any, doc?: this) => T;

/** defines a custom setter for this property using [`Object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). */
set?: (value: any, priorVal?: T, doc?: this) => any;

/** array of allowed values for this path. Allowed for strings, numbers, and arrays of strings */
enum?: Array<string | number | null> | ReadonlyArray<string | number | null> | { values: Array<string | number | null> | ReadonlyArray<string | number | null>, message?: string } | { [path: string]: string | number | null };

/** The default [subtype](http://bsonspec.org/spec.html) associated with this buffer when it is stored in MongoDB. Only allowed for buffer paths */
subtype?: number;

/** The minimum value allowed for this path. Only allowed for numbers and dates. */
min?: number | NativeDate | [number, string] | [NativeDate, string] | readonly [number, string] | readonly [NativeDate, string];

/** The maximum value allowed for this path. Only allowed for numbers and dates. */
max?: number | NativeDate | [number, string] | [NativeDate, string] | readonly [number, string] | readonly [NativeDate, string];

/** Defines a TTL index on this path. Only allowed for dates. */
expires?: string | number;

/** If `true`, Mongoose will skip gathering indexes on subpaths. Only allowed for subdocuments and subdocument arrays. */
excludeIndexes?: boolean;

/** If set, overrides the child schema's `_id` option. Only allowed for subdocuments and subdocument arrays. */
_id?: boolean;

/** If set, specifies the type of this map's values. Mongoose will cast this map's values to the given type. */
of?: Function | SchemaDefinitionProperty<any>;

/** If true, uses Mongoose's default `_id` settings. Only allowed for ObjectIds */
auto?: boolean;

/** Attaches a validator that succeeds if the data string matches the given regular expression, and fails otherwise. */
match?: RegExp | [RegExp, string] | readonly [RegExp, string];

/** If truthy, Mongoose will add a custom setter that lowercases this string using JavaScript's built-in `String#toLowerCase()`. */
lowercase?: boolean;

/** If truthy, Mongoose will add a custom setter that removes leading and trailing whitespace using JavaScript's built-in `String#trim()`. */
trim?: boolean;

/** If truthy, Mongoose will add a custom setter that uppercases this string using JavaScript's built-in `String#toUpperCase()`. */
uppercase?: boolean;

/** If set, Mongoose will add a custom validator that ensures the given string's `length` is at least the given number. */
minlength?: number | [number, string] | readonly [number, string];

/** If set, Mongoose will add a custom validator that ensures the given string's `length` is at most the given number. */
maxlength?: number | [number, string] | readonly [number, string];

[other: string]: any;
}
}

0 comments on commit 996e48d

Please sign in to comment.