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

Schema definition does not accept Schema instance as a value #9862

Closed
devagrawal09 opened this issue Jan 25, 2021 · 3 comments
Closed

Schema definition does not accept Schema instance as a value #9862

devagrawal09 opened this issue Jan 25, 2021 · 3 comments
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@devagrawal09
Copy link

Do you want to request a feature or report a bug?
Report a bug
What is the current behavior?
Here is the sample code

import { Document, Schema, SchemaDefinition } from "mongoose";

interface IProfile {
  age: Number;
}

interface ProfileDoc extends Document, IProfile {}

interface IUser {
  email: string;
  profile: IProfile;
}

interface UserDoc extends Document, IUser {};

const ProfileSchemaDef: SchemaDefinition<IProfile> = {
  age: Schema.Types.Number
};

const ProfileSchema = new Schema<ProfileDoc>(ProfileSchemaDef);

const UserSchemaDef: SchemaDefinition<IUser> = {
  email: String,
  profile: ProfileSchema
};

This code gives me the following error on the profile: ProfileSchema line

Type 'Schema<ProfileDoc, Model<ProfileDoc>>' is not assignable to type 'Schema<Document<any>, Model<Document<any>>>'.

However if I change it to profile: ProfileSchemaDef, the error goes away.

I looked into mongoose's .d.ts file, and it looks like the SchemaDefinitionProperty type is correctly expecting a Schema type. But when I give it a Schema instance, it fails. So I have to resort to providing a SchemaDefinition<T> instance.

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

Code provided above.

{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "lib":["ES2020"],
    "allowJs": true,
    "outDir": "build",
    "rootDir": ".",
    "sourceMap": true,

    "moduleResolution": "node",
    "baseUrl": "./src",
    "esModuleInterop": true,

    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    
    "preserveConstEnums": true,
    "resolveJsonModule": true,
    "pretty": true,
  },
  "include": ["src", "test"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

What is the expected behavior?
profile: ProfileSchema should not result in errors.

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

@devagrawal09
Copy link
Author

Update:
I changed

const ProfileSchema = new Schema<ProfileDoc>(ProfileSchemaDef);

to

const ProfileSchema = new Schema<ProfileDoc, any>(ProfileSchemaDef);

and now the UserSchemaDef seems to accept it just fine. However this is not the ideal solution.

@devagrawal09
Copy link
Author

One more update:
Getting rid of the type argument for Schema also fixed the issue.

const ProfileSchema = new Schema(ProfileSchemaDef);

This seems like a much more ideal solution. However, I still think the the original form of the definition should work, since ProfileDoc is an extension of IProfile. Please let me know if you disagree.

@vkarpov15 vkarpov15 added this to the 5.11.15 milestone Jan 28, 2021
@vkarpov15 vkarpov15 added the typescript Types or Types-test related issue / Pull Request label Jan 28, 2021
@vkarpov15
Copy link
Collaborator

Part of the issue is that the type of profile in IUser needs to inherit from Document. The below code will work once we ship Mongoose 5.11.15:

import { Document, Schema, SchemaDefinition, Model } from "mongoose";

interface IProfile {
  age: Number;
}

interface ProfileDoc extends Document, IProfile {}

interface IUser {
  email: string;
  profile: ProfileDoc; // <-- changed
}

interface UserDoc extends Document, IUser {};

const ProfileSchemaDef: SchemaDefinition<IProfile> = {
  age: Schema.Types.Number
};

const ProfileSchema = new Schema<ProfileDoc, Model<ProfileDoc>, ProfileDoc>(ProfileSchemaDef); // <-- added generics

const UserSchemaDef: SchemaDefinition<IUser> = {
  email: String,
  profile: ProfileSchema
};

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

2 participants