Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions test/types/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1920,3 +1920,33 @@ function gh15536() {
const user3 = new UserModelNameRequiredCustom({ name: null });
expectType<string>(user3.name);
}

function gh10894() {
function autoInferred() {
const schema = new Schema({
testProp: {
type: 'Union',
of: [String, Number]
}
});
const TestModel = model('Test', schema);

type InferredDocType = InferSchemaType<typeof schema>;
expectType<string | number | null | undefined>({} as InferredDocType['testProp']);

const doc = new TestModel({ testProp: 42 });
expectType<string | number | null | undefined>(doc.testProp);

const toObject = doc.toObject();
expectType<string | number | null | undefined>(toObject.testProp);

const schemaDefinition = {
testProp: {
type: 'Union',
of: ['String', 'Number']
}
} as const;
type RawDocType = InferRawDocType<typeof schemaDefinition>;
expectType<string | number | null | undefined>({} as RawDocType['testProp']);
}
}
19 changes: 12 additions & 7 deletions types/inferrawdoctype.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ declare module 'mongoose' {
TypeKey
>;

type UnionToRawPathType<T extends readonly any[]> = T[number] extends infer U
? ResolveRawPathType<U>
: never;

/**
* Same as inferSchemaType, except:
*
Expand Down Expand Up @@ -109,11 +113,12 @@ declare module 'mongoose' {
IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
PathValueType extends MapConstructor | 'Map' ? Map<string, ResolveRawPathType<Options['of']>> :
IfEquals<PathValueType, typeof Schema.Types.Map> extends true ? Map<string, ResolveRawPathType<Options['of']>> :
PathValueType extends ArrayConstructor ? any[] :
PathValueType extends typeof Schema.Types.Mixed ? any:
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
IfEquals<PathValueType, {}> extends true ? any:
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
PathValueType extends Record<string, any> ? InferRawDocType<PathValueType> :
unknown;
PathValueType extends 'Union' | 'union' | typeof Schema.Types.Union ? Options['of'] extends readonly any[] ? UnionToRawPathType<Options['of']> : never :
PathValueType extends ArrayConstructor ? any[] :
PathValueType extends typeof Schema.Types.Mixed ? any:
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
IfEquals<PathValueType, {}> extends true ? any:
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
PathValueType extends Record<string, any> ? InferRawDocType<PathValueType> :
unknown;
}
19 changes: 12 additions & 7 deletions types/inferschematype.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ TypeHint<PathValueType>
*/
type PathEnumOrString<T extends SchemaTypeOptions<string>['enum']> = T extends ReadonlyArray<infer E> ? E : T extends { values: any } ? PathEnumOrString<T['values']> : T extends Record<string, infer V> ? V : string;

type UnionToType<T extends readonly any[]> = T[number] extends infer U
? ResolvePathType<U>
: never;

type IsSchemaTypeFromBuiltinClass<T> = T extends (typeof String)
? true
: T extends (typeof Number)
Expand Down Expand Up @@ -314,11 +318,12 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
PathValueType extends MapConstructor | 'Map' ? Map<string, ResolvePathType<Options['of']>> :
IfEquals<PathValueType, typeof Schema.Types.Map> extends true ? Map<string, ResolvePathType<Options['of']>> :
PathValueType extends ArrayConstructor ? any[] :
PathValueType extends typeof Schema.Types.Mixed ? any:
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: TypeKey }> :
unknown,
PathValueType extends 'Union' | 'union' | typeof Schema.Types.Union ? Options['of'] extends readonly any[] ? UnionToType<Options['of']> : never :
PathValueType extends ArrayConstructor ? any[] :
PathValueType extends typeof Schema.Types.Mixed ? any:
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: TypeKey }> :
unknown,
TypeHint>;
9 changes: 8 additions & 1 deletion types/schematypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ declare module 'mongoose' {
_id?: boolean;

/** If set, specifies the type of this map's values. Mongoose will cast this map's values to the given type. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should likely mention that the property is also valid for Union now.

of?: Function | SchemaDefinitionProperty<any>;
of?: Function | SchemaDefinitionProperty<any> | (Function | SchemaDefinitionProperty<any>)[];

/** If true, uses Mongoose's default `_id` settings. Only allowed for ObjectIds */
auto?: boolean;
Expand Down Expand Up @@ -569,6 +569,13 @@ declare module 'mongoose' {
static defaultOptions: Record<string, any>;
}

class Union extends SchemaType {
static schemaName: 'Union';

/** Default options for this SchemaType */
static defaultOptions: Record<string, any>;
}

class UUID extends SchemaType {
/** This schema type's name, to defend against minifiers that mangle function names. */
static schemaName: 'UUID';
Expand Down