UNPKG

7.46 kBTypeScriptView Raw
1import {
2 IsSchemaTypeFromBuiltinClass,
3 RequiredPaths,
4 OptionalPaths,
5 PathWithTypePropertyBaseType,
6 PathEnumOrString
7} from './inferschematype';
8
9declare module 'mongoose' {
10 export type InferRawDocType<
11 DocDefinition,
12 TSchemaOptions extends Record<any, any> = DefaultSchemaOptions
13 > = {
14 [
15 K in keyof (RequiredPaths<DocDefinition, TSchemaOptions['typeKey']> &
16 OptionalPaths<DocDefinition, TSchemaOptions['typeKey']>)
17 ]: ObtainRawDocumentPathType<DocDefinition[K], TSchemaOptions['typeKey']>;
18 };
19
20 /**
21 * @summary Obtains schema Path type.
22 * @description Obtains Path type by separating path type from other options and calling {@link ResolvePathType}
23 * @param {PathValueType} PathValueType Document definition path type.
24 * @param {TypeKey} TypeKey A generic refers to document definition.
25 */
26 type ObtainRawDocumentPathType<
27 PathValueType,
28 TypeKey extends string = DefaultTypeKey
29 > = ResolveRawPathType<
30 PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? PathValueType[TypeKey] : PathValueType,
31 PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? Omit<PathValueType, TypeKey> : {},
32 TypeKey
33 >;
34
35 /**
36 * Same as inferSchemaType, except:
37 *
38 * 1. Replace `Types.DocumentArray` and `Types.Array` with vanilla `Array`
39 * 2. Replace `ObtainDocumentPathType` with `ObtainRawDocumentPathType`
40 * 3. Replace `ResolvePathType` with `ResolveRawPathType`
41 *
42 * @summary Resolve path type by returning the corresponding type.
43 * @param {PathValueType} PathValueType Document definition path type.
44 * @param {Options} Options Document definition path options except path type.
45 * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition".
46 * @returns Number, "Number" or "number" will be resolved to number type.
47 */
48 type ResolveRawPathType<PathValueType, Options extends SchemaTypeOptions<PathValueType> = {}, TypeKey extends string = DefaultSchemaOptions['typeKey']> =
49 PathValueType extends Schema ?
50 InferSchemaType<PathValueType> :
51 PathValueType extends (infer Item)[] ?
52 IfEquals<Item, never, any[], Item extends Schema ?
53 // If Item is a schema, infer its type.
54 Array<InferSchemaType<Item>> :
55 Item extends Record<TypeKey, any> ?
56 Item[TypeKey] extends Function | String ?
57 // If Item has a type key that's a string or a callable, it must be a scalar,
58 // so we can directly obtain its path type.
59 ObtainRawDocumentPathType<Item, TypeKey>[] :
60 // If the type key isn't callable, then this is an array of objects, in which case
61 // we need to call ObtainDocumentType to correctly infer its type.
62 Array<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
63 IsSchemaTypeFromBuiltinClass<Item> extends true ?
64 ObtainRawDocumentPathType<Item, TypeKey>[] :
65 IsItRecordAndNotAny<Item> extends true ?
66 Item extends Record<string, never> ?
67 ObtainRawDocumentPathType<Item, TypeKey>[] :
68 Array<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
69 ObtainRawDocumentPathType<Item, TypeKey>[]
70 >:
71 PathValueType extends ReadonlyArray<infer Item> ?
72 IfEquals<Item, never, any[], Item extends Schema ?
73 Array<InferSchemaType<Item>> :
74 Item extends Record<TypeKey, any> ?
75 Item[TypeKey] extends Function | String ?
76 ObtainRawDocumentPathType<Item, TypeKey>[] :
77 ObtainDocumentType<Item, any, { typeKey: TypeKey }>[]:
78 IsSchemaTypeFromBuiltinClass<Item> extends true ?
79 ObtainRawDocumentPathType<Item, TypeKey>[] :
80 IsItRecordAndNotAny<Item> extends true ?
81 Item extends Record<string, never> ?
82 ObtainRawDocumentPathType<Item, TypeKey>[] :
83 Array<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
84 ObtainRawDocumentPathType<Item, TypeKey>[]
85 >:
86 PathValueType extends StringSchemaDefinition ? PathEnumOrString<Options['enum']> :
87 IfEquals<PathValueType, Schema.Types.String> extends true ? PathEnumOrString<Options['enum']> :
88 IfEquals<PathValueType, String> extends true ? PathEnumOrString<Options['enum']> :
89 PathValueType extends NumberSchemaDefinition ? Options['enum'] extends ReadonlyArray<any> ? Options['enum'][number] : number :
90 IfEquals<PathValueType, Schema.Types.Number> extends true ? number :
91 PathValueType extends DateSchemaDefinition ? Date :
92 IfEquals<PathValueType, Schema.Types.Date> extends true ? Date :
93 PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
94 PathValueType extends BooleanSchemaDefinition ? boolean :
95 IfEquals<PathValueType, Schema.Types.Boolean> extends true ? boolean :
96 PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId :
97 IfEquals<PathValueType, Types.ObjectId> extends true ? Types.ObjectId :
98 IfEquals<PathValueType, Schema.Types.ObjectId> extends true ? Types.ObjectId :
99 PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 :
100 IfEquals<PathValueType, Schema.Types.Decimal128> extends true ? Types.Decimal128 :
101 IfEquals<PathValueType, Types.Decimal128> extends true ? Types.Decimal128 :
102 IfEquals<PathValueType, Schema.Types.BigInt> extends true ? bigint :
103 IfEquals<PathValueType, BigInt> extends true ? bigint :
104 PathValueType extends 'bigint' | 'BigInt' | typeof Schema.Types.BigInt | typeof BigInt ? bigint :
105 PathValueType extends 'uuid' | 'UUID' | typeof Schema.Types.UUID ? Buffer :
106 IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
107 PathValueType extends MapConstructor | 'Map' ? Map<string, ResolveRawPathType<Options['of']>> :
108 IfEquals<PathValueType, typeof Schema.Types.Map> extends true ? Map<string, ResolveRawPathType<Options['of']>> :
109 PathValueType extends ArrayConstructor ? any[] :
110 PathValueType extends typeof Schema.Types.Mixed ? any:
111 IfEquals<PathValueType, ObjectConstructor> extends true ? any:
112 IfEquals<PathValueType, {}> extends true ? any:
113 PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
114 PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, { typeKey: TypeKey }> :
115 unknown;
116}