Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.97k stars 3.84k forks source link

Plugin function signature "is not assignable to type" #11831

Closed infiniityr closed 2 years ago

infiniityr commented 2 years ago

Do you want to request a feature or report a bug?

Report a bug

What is the current behavior?

When creating a plugin in Typescript, It is not possible to specify in the function a custom Model signature.

If the current behavior is a bug, please provide the steps to reproduce.

In my plugin

export interface ISearchableModel<T = ISearchable> extends Model<T>{
    fuzzySearch(searchterm:string, limited:boolean): Promise<T[]>
    searchables(): string[]
    searchableFields(): string[]
}

export interface ISearchable extends Document {
    search: string[]
    searchables (): string[]
}

const searchPlugin = (schema:Schema<ISearchable, ISearchableModel>, opts?: any) => {
    // function
}

When I want to use the plugin

export interface IMyObject extends ISearchable {

}

export interface IMyObjectModel extends ISearchableModel<IMyObject> {

}

const MyObjectSchema = new Schema<IMyObject, IMyObjectModel>({
    // Definition of the schema
})

MyObjectSchema.plugin(searchPlugin) // Here is the error

I have the following Typescript error.

'Schema<IMyObject, Model<IMyObject, any, any, any>, {}, {}>' is not assignable to type 'Schema<ISearchable, ISearchableModel<ISearchable>, {}, {}>'

What is the expected behavior?

This should work because ISearchableModel extends Model.

From what I seen, the issue is only on the Model<IMyObject> part.

If I set the signature of my plugin function as follow, it works for Typescript (but not for me...)

const searchPlugin = (schema:Schema<ISearchable, Model<ISearchable>>, opts?: any) => {
    // function
}

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

NodeJS : v16.13.0 Mongoose : v6.3.4

IslandRhythms commented 2 years ago

I'm not getting your error message but I am getting an error message: type instantiation is deep and possibly infinite.

infiniityr commented 2 years ago

At least the error is more explicite in your case ! Do you have an idea why it says so ?

Uzlopak commented 2 years ago

I can not reproduce it. I added your code into schema.test.ts

function gh11831() {
  interface ISearchableModel<T = ISearchable> extends Model<T> {
    fuzzySearch(searchterm: string, limited: boolean): Promise<T[]>
    searchables(): string[]
    searchableFields(): string[]
  }

  interface ISearchable extends Document {
    search: string[]
    searchables(): string[]
  }

  const searchPlugin = (schema: Schema<ISearchable, Model<ISearchable>>, opts?: any) => { }
  interface IMyObject extends ISearchable { }

  interface IMyObjectModel extends ISearchableModel<IMyObject> {
  }

  const MyObjectSchema = new Schema<IMyObject, IMyObjectModel>({
    // Definition of the schema
  })

  MyObjectSchema.plugin(searchPlugin);
}

Can you give me a working snippet, which results in your error?

infiniityr commented 2 years ago

I don't understand, I can't reproduce my error anymore... It looks like the version of Typescript have been upgraded from 4.6.4 to 4.7.2.

@IslandRhythms Have you managed to reproduce it ? Or partially reproduce it ?

Here is my environment :