Skip to content

Commit 2cbe0a0

Browse files
Add ability to infer path of mixed array type.
1 parent fa889a3 commit 2cbe0a0

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

test/types/schema.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Schema, Document, SchemaDefinition, Model, Types, InferSchemaType, SchemaType, Query, HydratedDocument } from 'mongoose';
22
import { expectType, expectError, expectAssignable } from 'tsd';
3+
import { IsTAny } from '../../types/inferschematype';
34

45
enum Genre {
56
Action,
@@ -359,6 +360,10 @@ export function autoTypedSchema() {
359360
customSchema?: Int8;
360361
map1?: Map<string, string>;
361362
map2?: Map<string, number>;
363+
array1?: string[];
364+
array2?: Schema.Types.Mixed[];
365+
array3?: Schema.Types.Mixed[];
366+
array4?: Schema.Types.Mixed[];
362367
};
363368

364369
const TestSchema = new Schema({
@@ -390,7 +395,11 @@ export function autoTypedSchema() {
390395
objectId3: 'objectId',
391396
customSchema: Int8,
392397
map1: { type: Map, of: String },
393-
map2: { type: Map, of: Number }
398+
map2: { type: Map, of: Number },
399+
array1: { type: [String] },
400+
array2: { type: Array },
401+
array3: { type: [Schema.Types.Mixed] },
402+
array4: { type: [{}] }
394403
});
395404

396405
type InferredTestSchemaType = InferSchemaType<typeof TestSchema>;

types/inferschematype.d.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ declare module 'mongoose' {
2323
* // result
2424
* type UserType = {userName?: string}
2525
*/
26-
type InferSchemaType<SchemaType> = SchemaType extends Schema<infer DocType>
27-
? IsItRecordAndNotAny<DocType> extends true ? DocType : ObtainSchemaGeneric<SchemaType, 'DocType'>
26+
type InferSchemaType<SchemaType> = SchemaType extends Schema<infer EnforcedDocType>
27+
? IsItRecordAndNotAny<EnforcedDocType> extends true ? EnforcedDocType : ObtainSchemaGeneric<SchemaType, 'DocType'>
2828
: unknown;
2929

3030
/**
@@ -51,7 +51,9 @@ declare module 'mongoose' {
5151
* @param {T} T A generic type to be checked.
5252
* @returns true if {@link T} is Record OR false if {@link T} is of any type.
5353
*/
54-
type IsItRecordAndNotAny<T> = T extends any[] ? false : T extends Record<any, any> ? true : false;
54+
type IsItRecordAndNotAny<T> = IsTAny<T> extends true ? false : T extends Record<any, any> ? true : false;
55+
56+
type IsTAny<T> = keyof any extends keyof T ? (unknown extends T ? true : false) : false;
5557

5658
/**
5759
* @summary Required path base type.
@@ -128,15 +130,17 @@ type PathEnumOrString<T extends SchemaTypeOptions<string>['enum']> = T extends (
128130
* @returns Number, "Number" or "number" will be resolved to string type.
129131
*/
130132
type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueType> = {}> =
131-
PathValueType extends (infer Item)[] ? ResolvePathType<Item>[] :
132-
PathValueType extends StringConstructor | 'string' | 'String' | typeof Schema.Types.String ? PathEnumOrString<Options['enum']> :
133-
PathValueType extends NumberConstructor | 'number' | 'Number' | typeof Schema.Types.Number ? number :
134-
PathValueType extends DateConstructor | 'date' | 'Date' | typeof Schema.Types.Date ? Date :
135-
PathValueType extends BufferConstructor | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
136-
PathValueType extends BooleanConstructor | 'boolean' | 'Boolean' | typeof Schema.Types.Boolean ? boolean :
137-
PathValueType extends 'objectId' | 'ObjectId' | typeof Schema.Types.ObjectId ? Schema.Types.ObjectId :
138-
PathValueType extends ObjectConstructor | typeof Schema.Types.Mixed ? Schema.Types.Mixed :
139-
keyof PathValueType extends never ? Schema.Types.Mixed :
140-
PathValueType extends MapConstructor ? Map<string, ResolvePathType<Options['of']>> :
141-
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
142-
unknown;
133+
IsTAny<PathValueType> extends true ? Schema.Types.Mixed:
134+
PathValueType extends (infer Item)[] ? ResolvePathType<Item>[] :
135+
PathValueType extends StringConstructor | 'string' | 'String' | typeof Schema.Types.String ? PathEnumOrString<Options['enum']> :
136+
PathValueType extends NumberConstructor | 'number' | 'Number' | typeof Schema.Types.Number ? number :
137+
PathValueType extends DateConstructor | 'date' | 'Date' | typeof Schema.Types.Date ? Date :
138+
PathValueType extends BufferConstructor | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
139+
PathValueType extends BooleanConstructor | 'boolean' | 'Boolean' | typeof Schema.Types.Boolean ? boolean :
140+
PathValueType extends 'objectId' | 'ObjectId' | typeof Schema.Types.ObjectId ? Schema.Types.ObjectId :
141+
PathValueType extends ObjectConstructor | typeof Schema.Types.Mixed ? Schema.Types.Mixed :
142+
PathValueType extends MapConstructor ? Map<string, ResolvePathType<Options['of']>> :
143+
PathValueType extends ArrayConstructor ? Schema.Types.Mixed[] :
144+
keyof PathValueType extends keyof {} ? Schema.Types.Mixed :
145+
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
146+
unknown;

0 commit comments

Comments
 (0)