简体   繁体   中英

TypeScript: Argument of type is not assignable

TypeScript newbie here migrating an existing project. We have Mongoose models, which look similar to the following snippet and use the discriminatorKey property:

const task = new mongoose.Schema({
  name: {
    type: String
  },
  notes: {
    type: String
  }
}, {
  discriminatorKey: 'type',
  toObject: {
    virtuals: true
  },
  toJSON: {
    virtuals: true
  }
});

This gives me the following error during compilation:

src/models/task.ts(12,3): error TS2345: Argument of type '{ discriminatorKey: string; }' is not assignable to parameter of type 'SchemaOptions'.
  Object literal may only specify known properties, and 'discriminatorKey' does not exist in type 'SchemaOptions'.

I'm using these @types definition, which seems to be the most recent one:

"@types/mongoose": "^4.7.8"

I understand, that the type definitions do not specify the discriminatorKey (this is obviously visible when looking at node_modules/@types/mongoose/index.d.ts ), but I do not understand (a) why (oversight? different version? other reason?), (b) how can I circumvent this error?

(c) Bonus question: The versioning strategy of the @types definitions is still unclear to me. I would assume, that the type definitions should match the version of the actual library, however, often there does not seem to be a matching version -- eg we're using express version. 4.13.4, but there is no matching @types/express version available. What's the best practice to follow in this case?

I'm a bit late, but I have just come across the same issue. I'm using @types/mongoose 4.7.12 and it hasn't been updated yet.

As a temporal solutions, when you come across this kind of issues, you have two options:

🤦 Cast the whole problematic object to any

As you are defining the options inline, you can cast them to any :

const task: mongoose.Schema = new mongoose.Schema({ ... }, {
    discriminatorKey: 'type',

    ...
} as any);

or

const task: mongoose.Schema = new mongoose.Schema({ ... }, <any> {
    discriminatorKey: 'type',

    ...
});

The downside of this approach is that now type checking for that SchemaOptions object will be disabled for all the properties, so if you make a typo in, let's say, toJSON , and type toJSNO instead, TypeScript will not warn you.

👌 Cast the problematic object to any just in the statement that uses unknown properties

A different approach to keep type checking working for the known properties but disable it for the yet unknown ones is to define that options object before with the known properties and add the unknown ones later casting them to any :

const options: mongoose.SchemaOptions = {
    toObject: { virtuals: true },
    toJSON: { virtuals: true },
};

(options as any).discriminatorKey = 'type';

// or (<any> options).discriminatorKey = 'type';

const task = new mongoose.Schema({ ... }, options);

🙏 Side note: Please, contribute!

If you find any similar issue in this package or in any other in the future, this is a really easy and minimal change that you can fix and PR to DefinitelyTyped . Actually, for something like this you don't even need to clone the repo, I was able to do it just by using the edit button in GitHub.

Here's the PR: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/16598 , once it is merged, just update to the most recent version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM