Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS] model, new Model, Document and HydratedDocument: DocType typing inconsistencies #12573

Closed
1 task done
andreafdaf opened this issue Oct 20, 2022 · 1 comment · Fixed by #12659
Closed
1 task done
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@andreafdaf
Copy link

andreafdaf commented Oct 20, 2022

Prerequisites

  • I have written a descriptive issue title

Mongoose version

6.6.5

Node.js version

16.18.0

MongoDB server version

6.0

Typescript version (if applicable)

4.8.4

Description

This issue is possibly related to #10302

We are migrating from v5 to v6 and the situation in v6 is weirder than in v5.

It seems to me (in my really humble opinion) that DocType is not working as expected both when specifying what we pass to new MyModel but also when trying to tell us what comes back from model.

I think that the main issue is that DocType is only used to tell the Document what it should accept in some methods or the lean shape it returns, while it is HydratedDocument that merges the definition of DocType and Document, leaving some edge cases on how HydratedDocument handles it's DocType and how it is handled when calling new MyModel()

Steps to Reproduce

// ./schema.ts
import { Schema } from 'mongoose'

export const MySchema = new Schema({
  field: { type: String }
})

OK:

import { model } from 'mongoose'
import { MySchema } from './schema'

const MyModel = model('My', MySchema)

const myDocument = new MyModel({ field: 'a' })
const { field } = myDocument
import { model } from 'mongoose'
import { MySchema } from './schema'

const MyModel = model<{ field: string }>('My', MySchema)

const myDocument = new MyModel({ field: 'a' })
const { field } = myDocument
import { model } from 'mongoose'
import { MySchema } from './schema'

const MyModel = model('My', MySchema)

const myDocument = new MyModel<any>({ field: 'a' })
const { field } = myDocument // it doesn't care that I passed <any> to MyModel, it makes no difference and behaves like above
import { model, HydratedDocument } from 'mongoose'
import { MySchema } from './schema'

const MyModel = model('My', MySchema)

const myDocument: HydratedDocument<any> = new MyModel({ field: 'a' })
const { field } = myDocument // myDocument is 'any'

KO:

import { model, Schema } from 'mongoose'
import { MySchema } from './schema'

const MyModel = model<any>('My', MySchema)

const myDocument = new MyModel({ field: 'a' })
const { field } = myDocument // Property 'field' does not exist on type 'Document<unknown, any, unknown> & { _id: ObjectId; }'.ts(2339)
import { model, Schema } from 'mongoose'
import { MySchema } from './schema'

model('My', MySchema)
const MyModel = model<any>('My')

const myDocument = new MyModel({ field: 'a' })
const { field } = myDocument // Property 'field' does not exist on type 'Document<unknown, any, unknown> & { _id: ObjectId; }'.ts(2339)
import { model, Schema } from 'mongoose'
import { MySchema } from './schema'

model('My', MySchema)
const MyModel = model('My')

const myDocument = new MyModel<any>({ field: 'a' })
const { field } = myDocument // Property 'field' does not exist on type 'Document<unknown, any, unknown> & { _id: ObjectId; }'.ts(2339)

Expected Behavior

I would expect const MyModel = model<any>('My', MySchema); const myDocument = new MyModel({ ... }) to behave like HydratedDocument<any>.

I would expect const MyModel = model<any>('My'); const myDocument = new MyModel({ ... }) to behave like HydratedDocument<any>.

I would expect const myDocument = new MyModel<any>({ field: 'a' }) to behave like HydratedDocument<any>.

@andreafdaf andreafdaf changed the title [TS] model and Document DocType typing inconsistencies [TS] model, new Model, Document and HydratedDocument: DocType typing inconsistencies Oct 21, 2022
@IslandRhythms IslandRhythms added the typescript Types or Types-test related issue / Pull Request label Oct 24, 2022
@IslandRhythms
Copy link
Collaborator

import { Schema } from 'mongoose'

const MySchema = new Schema({
  field: { type: String }
})

import { model } from 'mongoose'
/*
const MyModel = model('My', MySchema)

const myDocument = new MyModel({ field: 'a' })
const { field } = myDocument
*/

const MyModel = model<any>('My', MySchema)

const myDocument = new MyModel({ field: 'a' })
const { field } = myDocument // Property 'field' does not exist on type 'Document<unknown, any, unknown> & { _id: ObjectId; }'.ts(2339)

@vkarpov15 vkarpov15 added this to the 6.6.9 milestone Oct 24, 2022
@vkarpov15 vkarpov15 modified the milestones: 6.7.3, 6.7.2 Nov 4, 2022
vkarpov15 added a commit that referenced this issue Nov 4, 2022
vkarpov15 added a commit that referenced this issue Nov 7, 2022
fix(types): correct handling for model<any>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants