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] "insertMany" dosnt filter out functions #10144

Closed
hasezoey opened this issue Apr 16, 2021 · 1 comment
Closed

[Types] "insertMany" dosnt filter out functions #10144

hasezoey opened this issue Apr 16, 2021 · 1 comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@hasezoey
Copy link
Collaborator

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

What is the current behavior?
Model.insertMany(here) dosnt filter out functions

Error (taken from code below):

(property) someProp: string
No overload matches this call.
  The last overload gave the following error.
    Type '{ someProp: string; }' is not assignable to type 'DocumentType<User, BeAnObject> | _AllowStringsForIds<LeanDocument<DocumentType<User, BeAnObject>>>'.
      Property 'someFunction' is missing in type '{ someProp: string; }' but required in type '_AllowStringsForIds<LeanDocument<DocumentType<User, BeAnObject>>>'.ts(2769)

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

// NodeJS: 14.16.1
import * as mongoose from "mongoose"; // mongoose@5.12.4

class User {
  public someProp!: string;
}

// Note: "ModelType" and "ReturnModelType" are seperated, because they are used in different stages & with different cases in mind
type DocumentType<T, QueryHelpers = BeAnObject> = (T extends { _id: unknown; }
  ? mongoose.Document<T["_id"], QueryHelpers> & T
  : mongoose.Document<any, QueryHelpers> & T) &
  IObjectWithSomeFunction; // this is here, because all models / documents made with this have this at runtime

type ModelType<T, QueryHelpers = BeAnObject> = mongoose.Model<DocumentType<T, QueryHelpers>, QueryHelpers>;
// the "& U" is to add all "statics" (like static functions) onto the model type
type ReturnModelType<U extends AnyParamConstructor<any>, QueryHelpers = BeAnObject> = ModelType<InstanceType<U>, QueryHelpers> & U;

type AnyParamConstructor<T> = new (...args: any) => T;
type BeAnObject = Record<string, any>;
interface IObjectWithSomeFunction {
  someFunction(): string;
}

const UserSchema = new mongoose.Schema({ someProp: String, someOtherProp: [String] });
const UserModel: ReturnModelType<typeof User> = mongoose.model<DocumentType<User>, ReturnModelType<typeof User>>("User", UserSchema);

(async () => {
  await mongoose.connect(`mongodb://localhost:27017/`, { useNewUrlParser: true, dbName: "verifyMASTER", useCreateIndex: true, useUnifiedTopology: true });

  // the following code line is what errors
  await UserModel.insertMany([{ someProp: "hello" }]);

  await mongoose.disconnect();
})();
{
    "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/**/*"
    ]
}

What is the expected behavior?
that the mentioned function filters out functions

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

PS:
the provided code is taken from trying to upgrade typegoose, and modified to be un-typegoosed ("native mongoose" only)

@IslandRhythms IslandRhythms added pending release 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 typescript Types or Types-test related issue / Pull Request and removed pending release labels Apr 16, 2021
@vkarpov15 vkarpov15 removed the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Apr 23, 2021
@vkarpov15 vkarpov15 added this to the 5.12.6 milestone Apr 23, 2021
@vkarpov15
Copy link
Collaborator

I took a closer look at this, and unfortunately this is expected behavior. TypeScript can't accurately infer what properties are functions when using generic types: microsoft/TypeScript#43281, see discussion from #9989.

So if we want to filter out function property names, we'd have to somehow forbid using T & Document or class Foo<T> extends Document.

Realistically, I think we're going to have to add a new generic to the Model class that contains methods, and add any as an accepted parameter to create() and insertMany().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

No branches or pull requests

3 participants