nuxt-mongoose icon indicating copy to clipboard operation
nuxt-mongoose copied to clipboard

Difficulty with typeScript model definitions and generic declarations in mongoose

Open tarkantoan opened this issue 1 year ago • 2 comments

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 avatar Jul 14 '23 23:07 tarkantoan

@tarkantoan Sure! PR is welcome. Thanks

arashsheyda avatar Jul 15 '23 07:07 arashsheyda

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
}

xarenas107 avatar Dec 20 '23 16:12 xarenas107