Typescript: Typed model lacking type inference within the definitions of static and instance methods
See original GitHub issueDo you want to request a feature or report a bug? bug?
What is the current behavior? When constructing a model that uses Typescript and contains type definitions for static and instance methods, the types of those methods are not “inferred” when implementing the methods later on. A code example is below that might make things clearer.
If the current behavior is a bug, please provide the steps to reproduce. See this script:
import { Schema, Model, createConnection } from 'mongoose'
interface ITestModel {
name: string
}
interface InstanceMethods {
iMethod1: (param1: string) => string
iMethod2: (param1: string) => string
}
interface TestModel extends Model<ITestModel, {}, InstanceMethods> {
sMethod1: (param1: string) => string
sMethod2: (param1: string) => string
}
const ModelSchema = new Schema<ITestModel, TestModel>({
name: String
})
// NOT a type error (incorrect)
ModelSchema.statics.sMethod1 = function() {
// type error (correct, params are wrong)
this.sMethod2()
}
// NOT a type error (incorrect)
ModelSchema.statics.sMethod2 = function() {
}
// NOT a type error (incorrect)
ModelSchema.methods.iMethod1 = function() {
// type error (incorrect, this method exists)
this.iMethod2("test")
}
// NOT a type error (incorrect)
ModelSchema.methods.iMethod2 = function() {
}
// create lazy connection object to connect later
const connection = createConnection()
export const TestModelCompiled = connection.model<ITestModel, TestModel>("testModel", ModelSchema)
const modelInstance = new TestModelCompiled()
// type error (correct, method exists but param omitted)
modelInstance.iMethod1()
// type error (correct, method exists but param omitted)
TestModelCompiled.sMethod1()
What I was hoping for by defining the types for these models is that the implementations for each instance and static method would infer their types from the definitions provided to the schema. I would also expect that the this
context in both the instance and static methods would have knowledge of the other instance / static methods available on the model.
By this example:
- The instance and static methods themselves don’t seem to be inferring their types from the type definitions above. This is also the case when using the
schema.static('methodName, function() {})
style syntax. This allows me to implement the methods in a way that violates the type definitions - The static methods seem to be aware of the other static methods defined on the model, so when I call
this.sMethod2()
with no arguments I (correctly) get a type error. This is not the case in instance methods, wherethis.iMethod2()
tells me the method is not available.
Both instance and static methods have correct types when using them outside the model’s methods themselves, as seen on the last two lines.
This may also be due to a misunderstanding on my part of how to define the model’s types. I’m relatively new to Typescript so forgive me if I’m getting something wrong.
tsconfig.json
{
"compilerOptions": {
"allowJs": true,
"checkJs": false,
"esModuleInterop": true,
"skipLibCheck": true,
"noEmit": true,
"resolveJsonModule": true
},
"include": [
"server-src",
"lib",
"src",
"__tests__"
],
"exclude": [
"node_modules/**/*",
"../../node_modules/**/*"
]
}
What is the expected behavior? See above, I was expecting the instance and static methods to correctly infer their types from the model’s type definition, and for the instance method context to contain the other instance methods defined on the type.
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that “latest” is not a version. mongoose: 5.12.13 Node.js: 14.15.0 Typescript: 4.2.3
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:6
I can confirm the below script compiles successfully with 928ca4a. The issue is that you’ll need to add a 4th generic param to the
Schema
constructor as shown below:@shahar1 the code you pasted compiles fine with Mongoose 6.2, here’s a TypeScript playground: https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgWQgEwKYBsA0cDKAxgBYYgCGcAvnAGZQQhwDkIEAdgOYQQDOGzANwAoYcHYwMUWuUIY4ASQAqGXjFSYsiYXF1x25EBgBccNVHGdhVMRKky5i9mvLs5yDDGLpe2vXGAPL3QARlMACgBKOABeAD4zGAsua1tJaVl5FTUNbDgMAA9JdjRfXKwAHmVVdXRsPAQqPAVnGFd3T29ShIRRG0IONRQ6rCJSClj9DAB3AhIycirs2s08ZfLm1vaMIK7eOPDe-wMjU3wky2tI0WFysYWAOiNg0ofAztDJ2gBXNxhgDhRPx6KCeb5QdhwLzAXgPE7yAD0CLgAHVoABrXipIA
In the future, please open a new issue and follow the issue template.