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

Sub-schema Type Mismatch #9812

Closed
anubhab-parallel-reality opened this issue Jan 14, 2021 · 8 comments
Closed

Sub-schema Type Mismatch #9812

anubhab-parallel-reality opened this issue Jan 14, 2021 · 8 comments
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@anubhab-parallel-reality

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

What is the current behavior?
Schema inside schema (sub-schema) type mismatch

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

There is a Schema referring to GeoLocation, as per mongoose documentation, this following PointSchema.ts file is created

// PointSchema.ts ======

import { Document, Schema } from "mongoose";

export interface IGeoPoint {
    type: string
    coordinates: Array<number>
}

export interface IPoint extends IGeoPoint, Document {
    getGeoCoordinates(): IGeoCoordinate
}

const pointSchema: Schema<IPoint> = new Schema({
    type: {
        type: String,
        enum: ['Point'],
        required: true
    },
    coordinates: {
        type: [Number],
        required: true
    }
});

export interface IGeoCoordinate {
    lat: number
    lon: number
}

pointSchema.methods.getGeoCoordinates = function (this:IPoint): IGeoCoordinate {
    return {
        lat: this.coordinates[0],
        lon: this.coordinates[1]
    }
}

export default pointSchema

and another file LocationModel.ts which uses this PointsSchema.ts is created

// LocationModel.ts ======

import { Document, model, Schema } from "mongoose";
import PointSchema, { IPoint, IGeoCoordinate, IGeoPoint } from "../Schemas/PointSchema";

export interface ILocationDocument extends Document {
    location: IPoint
    name: string
    address: string
    getGeoCoordinate(): IGeoCoordinate
}

const LocationSchema: Schema<ILocationDocument> = new Schema({
    location: PointSchema,      // <---- error at this line
    name: String,
    address: String
})

LocationSchema.methods.getGeoCoordinate = function (this: ILocationDocument): IGeoCoordinate {
    return this.location.getGeoCoordinates()
}

export default model<ILocationDocument>("location", LocationSchema, 'locations')

Error at the marked line is:


Argument of type '{ location: Schema<IPoint, Model<IPoint>>; name: StringConstructor; address: StringConstructor; }' is not assignable to parameter of type '{ [path: string]: SchemaDefinitionProperty<undefined>; }'.
  Property 'location' is incompatible with index signature.
    Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'SchemaDefinitionProperty<undefined>'.
      Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'Schema<Document<any>, Model<Document<any>>>'.
        Types of property 'methods' are incompatible.
          Type '{ getGeoCoordinates: () => IGeoCoordinate; type: string; coordinates: number[]; _id?: any; __v?: number | undefined; $ignore: (path: string) => void; $isDefault: (path: string) => boolean; $isDeleted: (val?: boolean | undefined) => boolean; ... 48 more ...; validateSync: (pathsToValidate?: string[] | undefined, opti...' is not assignable to type '{ _id?: any; __v?: number | undefined; $ignore: (path: string) => void; $isDefault: (path: string) => boolean; $isDeleted: (val?: boolean | undefined) => boolean; $isEmpty: (path: string) => boolean; ... 47 more ...; validateSync: (pathsToValidate?: string[] | undefined, options?: any) => CallbackError; } & { ...; }'.
            Type '{ getGeoCoordinates: () => IGeoCoordinate; type: string; coordinates: number[]; _id?: any; __v?: number | undefined; $ignore: (path: string) => void; $isDefault: (path: string) => boolean; $isDeleted: (val?: boolean | undefined) => boolean; ... 48 more ...; validateSync: (pathsToValidate?: string[] | undefined, opti...' is not assignable to type '{ [name: string]: (this: Document<any>, ...args: any[]) => any; }'.
              Index signatures are incompatible.
                Type '(this: IPoint, ...args: any[]) => any' is not assignable to type '(this: Document<any>, ...args: any[]) => any'.
                  The 'this' types of each signature are incompatible.
                    Type 'Document<any>' is not assignable to type 'IPoint'.

My tsconfig.json file:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}

What is the expected behavior?
Sub-schema should be included by adapting the type of the schema

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Node: v14.7.0
mongoose: 5.11.11
@types/mongoose: 5.10.3
MongoDB: Atlas (version 4.2.11)

This issue was not seen in mongoose v5.9.13, and is seen in v5.11.11 (on probable enforcement of #9717)

Please update the documentation as per the updates and please let me know what I am missing here

@vkarpov15 vkarpov15 added this to the 5.11.13 milestone Jan 15, 2021
@vkarpov15 vkarpov15 added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Jan 15, 2021
@vkarpov15
Copy link
Collaborator

I tried compiling your script in a clean directory and it compiles without any errors. Please:

  1. Confirm your version of Mongoose by running npm list | grep "mongoose"
  2. Remove your dependency on @types/mongoose, that may be causing this error

@anubhab-parallel-reality
Copy link
Author

anubhab-parallel-reality commented Jan 19, 2021

now, that I downgraded to mongoose v5.9.13, it is compiling fine, let me get back on this after again trying out in a clean directory, but @types/mongoose is required by typescript

P.S: I accidentally closed the issue

@anubhab-parallel-reality
Copy link
Author

@vkarpov15 as you suggested, in a fresh directory, I did this:

Without @types/mongoose:
npm list | grep mongoose

├─┬ mongoose@5.11.12
│ ├── mongoose-legacy-pluralize@1.0.2

Compilation error:

LocationModel.ts(11,62): error TS2345: Argument of type '{ location: Schema<IPoint, Model<IPoint>>; name: StringConstructor; address: StringConstructor; }' is not assignable to parameter of type '{ [path: string]: SchemaDefinitionProperty<undefined>; }'.
  Property 'location' is incompatible with index signature.
    Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'SchemaDefinitionProperty<undefined>'.
      Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'Schema<Document<any>, Model<Document<any>>>'.
        Type 'Document<any>' is not assignable to type 'IPoint'.

With @types/mongoose:
npm list | grep mongoose

├─┬ @types/mongoose@5.10.3
├─┬ mongoose@5.11.12
│ ├── mongoose-legacy-pluralize@1.0.2

Compilation error:

LocationModel.ts(11,62): error TS2345: Argument of type '{ location: Schema<IPoint, Model<IPoint>>; name: StringConstructor; address: StringConstructor; }' is not assignable to parameter of type '{ [path: str
ing]: SchemaDefinitionProperty<undefined>; }'.
  Property 'location' is incompatible with index signature.
    Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'SchemaDefinitionProperty<undefined>'.
      Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'Schema<Document<any>, Model<Document<any>>>'.
        Type 'Document<any>' is missing the following properties from type 'IPoint': getGeoCoordinates, type, coordinates

Here, in this line:
Type 'Schema<IPoint, Model<IPoint>>' is not assignable to type 'Schema<Document<any>, Model<Document<any>>>'.
it says, cannot assign to type Document<any>, but, the interface ILocationDocument already defines that it is not Document<any> but IPoint which extends mongoose.Document

@vkarpov15 vkarpov15 added this to the 5.11.14 milestone Jan 20, 2021
@anubhab-parallel-reality
Copy link
Author

To further help to reproduce this issue, here, I provide these files and a Dockerfile to keep environments uniform

package.json:

{
  "name": "Test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/mongoose": "^5.10.3",
    "mongoose": "^5.11.12",
    "typescript": "^4.1.3"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}

Dockerfile:

FROM node:alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install -g typescript
RUN npm install
COPY . .
RUN tsc

The other files PointSchema.ts and LocationModel.ts remains same

@vkarpov15
Copy link
Collaborator

Try removing @types/mongoose, it is unnecessary if you're using Mongoose 5.11.

@vkarpov15 vkarpov15 removed this from the 5.11.14 milestone Jan 24, 2021
@anubhab-parallel-reality
Copy link
Author

Here, I've tried that already, and has the same outcome, I've also tried it in the Docker environment and it throws the same error

@vkarpov15 vkarpov15 added this to the 5.11.15 milestone Jan 28, 2021
@vkarpov15 vkarpov15 removed the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Jan 28, 2021
@IslandRhythms IslandRhythms added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue and removed confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. labels Jan 28, 2021
@vkarpov15
Copy link
Collaborator

I took a closer look at this and managed to confirm the issue, looks like I needed to run just tsc, not tsc ./LocationModel.ts to get this error. It looks like we already fixed this issue in #9862, so this issue will be fixed in v5.11.15, which we will ship in the next couple of days. Thanks for your patience!

@vkarpov15 vkarpov15 added typescript Types or Types-test related issue / Pull Request and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Feb 1, 2021
@anubhab-parallel-reality
Copy link
Author

Thanks for the action, looking forward to the update

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

No branches or pull requests

3 participants