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

[Types] "new generic({ properties })" does not work anymore since 5.13.4 #10526

Closed
hasezoey opened this issue Aug 1, 2021 · 1 comment
Closed
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@hasezoey
Copy link
Collaborator

hasezoey commented Aug 1, 2021

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

What is the current behavior?
since 5.13.4 new genericModel({ properties }) does not work anymore when in an generic context (even if restricted to extend from a class with the properties)

Re: #10475
Commit introducing the issue: 060039d

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

// NodeJS: 16.6.0
// MongoDB: 4.2-bionic (Docker)
import * as mongoose from "mongoose"; // mongoose@5.13.5

// when the "AnyKeys" in mongoose is replaced with this, it works
// type AnyKeys<T> = { [P in keyof T]?: T[P] | any };

class Testy {
  public prop1!: string;
  public prop2?: string;
}

// the following 2 functions should be the same in types, so they both have the error
function test1<U extends typeof Testy>(arg1: mongoose.Model<mongoose.Document & InstanceType<U>>) {
  const t = new arg1({ prop2: "hello" }); // error here
}
function test2<U extends Testy>(arg1: mongoose.Model<mongoose.Document & U>) {
  const t = new arg1({ prop2: "hello" }); // error here
}

// working, both of these blocks should be equal in types
const sch = new mongoose.Schema({ prop1: String, prop2: String });
sch.loadClass(Testy);
{
  const model: mongoose.Model<mongoose.Document<any, any> & InstanceType<typeof Testy>> = mongoose.model("testy1", sch);

  const t = new model({ prop2: "hello" });
}
{
  const model: mongoose.Model<mongoose.Document<any, any> & Testy> = mongoose.model("testy2", sch);

  const t = new model({ prop2: "hello" });
}

Note: the new AnyKeys type is basically like the one existing already, but removed the need for Partial, because it directly integrates ?, and the | undefined part (from Partial) should not be needed anymore, because it already has | any

Error (for both mentioned times):

Argument of type '{ prop2: string; }' is not assignable to parameter of type 'Partial<{ [P in keyof (Document<any, any, any> & InstanceType<U>)]: any; }> & AnyObject'.
  Type '{ prop2: string; }' is not assignable to type 'Partial<{ [P in keyof (Document<any, any, any> & InstanceType<U>)]: any; }>'.ts(2345)

tsconfig:

{
    "compileOnSave": true,
    "typeAcquisition": {
        "enable": true
    },
    "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "declarationMap": true,
        "outDir": "lib",
        "moduleResolution": "node",
        "target": "es6",
        "module": "commonjs",
        "newLine": "LF",
        "sourceMap": true,
        "removeComments": true,
        "strict": true,
        "allowUnreachableCode": false,
        "pretty": true,
        "declaration": true,
        "incremental": true,
        "tsBuildInfoFile": ".tsbuildinfo",
        "lib": [
            "esnext"
        ]
    },
    "include": [
        "src/**/*"
    ]
}

Reproduction Repository & branch: https://github.com/typegoose/typegoose-testing/tree/mongooseNewIssue
Reproduction File: https://github.com/typegoose/typegoose-testing/blob/mongooseNewIssue/src/test.ts

What is the expected behavior?
to not give an error

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


PS: because this took some time to find out and sometimes the types were too complex, #10525 came from it

@hasezoey hasezoey changed the title [Types] "new generic({ options })" does not work anymore since 5.13.5 [Types] "new generic({ properties })" does not work anymore since 5.13.4 Aug 1, 2021
@IslandRhythms IslandRhythms added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. typescript Types or Types-test related issue / Pull Request and removed confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. labels Aug 2, 2021
@vkarpov15 vkarpov15 added this to the 5.13.6 milestone Aug 3, 2021
@vkarpov15
Copy link
Collaborator

Thanks for finding this - apparently { [P in keyof T]?: T[P] | any } is different from Partial<{ [P in keyof T]: T[P] | any }>, although I haven't been able to figure out why. The below also fails:

  type __Partial<T> = {
    [P in keyof T]?: T[P];
  };
  type AnyKeys<T> = __Partial<{ [P in keyof T]: any }>;

So it doesn't look like an issue with Partial<> (https://www.typescriptlang.org/docs/handbook/advanced-types.html), maybe just a quirk with TypeScript not being able to handle nested definitions using [P in keyof T]?

Either way, your suggestion works so we'll use it 👍

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