Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.95k stars 3.84k forks source link

InferSchemaType does not infer subdocuments/nested paths #12011

Closed heilmela closed 2 years ago

heilmela commented 2 years ago

Prerequisites

Mongoose version

6.4.1

Node.js version

16.13.0

MongoDB server version

5.0

Description

Basically, I took the example from the docs and pluralized property name. The reslulting schema type is inferred as { ..., names?: unknown[] | undefined }.

The same thing happens when using a nested document, names: new Schema({}) and when using names: {type: [{...}]} the only array type which seems to be inferred correctly are primitive types e.g. names: [String] is inferred correctly as string[]

Steps to Reproduce

const schema = new mongoose.Schema({
  names: [{ type: String, required: true }],
  email: { type: String, required: true },
  avatar: String,
});

type User = InferSchemaType<typeof schema>;
// InferSchemaType will determine the type as follows:
// type User = {
//   email: string;
//   avatar?: string | undefined;
//   names?: unknown[] | undefined;
// };

Expected Behavior

const schema = new mongoose.Schema({
  names: [{ type: String, required: true }],
  email: { type: String, required: true },
  avatar: String,
});

type User = InferSchemaType<typeof schema>;
// InferSchemaType will determine the type as follows:
// type User = {
//   email: string;
//   avatar?: string | undefined;
//   name: string[] | undefined;
// };
heilmela commented 2 years ago

You might be correct, the example was a bit rash. However the problem still remains when using any non primitive array e.g.

const schema = new mongoose.Schema({
  names: {
    type: [
      {
        first: String,
        last: String,
      },
    ],
    required: true,
  },
  email: { type: String, required: true },
  avatar: String,
});
iammola commented 2 years ago

Yeah, you're right @heilmela ... I'm about to push a commit to fix that in the PR I've linked above. It should allow defining schema paths like this as well.

names: [{ type: String, required: true }],

The only issue is, that it'll match the string type but not make it required.

mohammad0-0ahmad commented 2 years ago

@heilmela Thanks for reporting this issue.