nuxt-mongoose
nuxt-mongoose copied to clipboard
Difficulty with typeScript model definitions and generic declarations in mongoose
Hello, I'm having difficulty defining models with TypeScript. Even though I've added Mongoose as a devDependency, I'm noticing some shortcomings in the generic declarations. If you'd like, I can do a little work and submit a pull request, or if you have a specific roadmap, could you please share it?
@tarkantoan Sure! PR is welcome. Thanks
You can try with something like this. Is not the prettiest solution but it should work .
import { model, Schema } from 'mongoose'
import type {
SchemaDefinition, SchemaOptions, Model, SchemaDefinitionType,
DefaultSchemaOptions, ApplySchemaOptions, ObtainDocumentType,
ResolveSchemaOptions, FlatRecord, InferSchemaType, ObtainSchemaGeneric, HydratedDocument
} from 'mongoose'
type Options<D,I,Q,S,V,H,O> = SchemaOptions<FlatRecord<D>, I, Q, S, V, H> | ResolveSchemaOptions<O>
type ApplyOptions<T,D,O> = ApplySchemaOptions<ObtainDocumentType<D, T, ResolveSchemaOptions<O>>,ResolveSchemaOptions<O>>
export function defineMongooseModel<T, I={}, Q={}, V={}, S={},
M = Model<T,Q,I,V>,
O = DefaultSchemaOptions,
D extends ApplyOptions<T,D,O> = ApplyOptions<T,any,O>,
H = HydratedDocument<FlatRecord<D>, V & I>,
TSchema = Schema<T, M, I, Q, V, S, O, D, H>
>(
document: string | {
name: string,
collection?: string
},
schema?: SchemaDefinition<SchemaDefinitionType<T>, T> | D,
options?: Options<D,I,Q,S,V,H,O>,
hooks?: (schema: Schema<T, M, I, Q, V, S, O, D, H>) => void,
): Model<
InferSchemaType<TSchema>,
ObtainSchemaGeneric<TSchema, 'TQueryHelpers'>,
ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>,
ObtainSchemaGeneric<TSchema, 'TVirtuals'>,
HydratedDocument<
InferSchemaType<TSchema>,
ObtainSchemaGeneric<TSchema, 'TVirtuals'> & ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>,
ObtainSchemaGeneric<TSchema, 'TQueryHelpers'>
>,
TSchema
> & ObtainSchemaGeneric<TSchema, 'TStaticMethods'>
export function defineMongooseModel<T,
O = DefaultSchemaOptions,
D extends ApplyOptions<T,D,O> = ApplyOptions<T,any,O>,
H = HydratedDocument<FlatRecord<D>>
>(
document: string | {
name: string,
collection?: string
},
definition?: SchemaDefinition<T>,
options?: Options<D,{},{},{},{},H,O>,
hooks?: (schema: Schema<T>) => void,
): Model<T>
export function defineMongooseModel(...args:any[]) {
const [document,schema,options,hooks] = args
const name = typeof document === 'string' ? document : document?.name
const collection = typeof document !== 'string' ? document?.collection : undefined
const $schema = new Schema(schema, options)
if (hooks) hooks($schema)
const $model = model(name, $schema, collection)
return $model
}