Automattic / mongoose

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

Make path in keyof T required in SchemaDefinition if T is supplied #14872

Open Grsz opened 1 month ago

Grsz commented 1 month ago

Prerequisites

🚀 Feature Proposal

In

export type SchemaDefinition<T = undefined, EnforcedDocType = any> = T extends undefined
    ? { [path: string]: SchemaDefinitionProperty; }
    : { [path in keyof T]?: SchemaDefinitionProperty<T[path], EnforcedDocType>; };

instead of just forcing the possible keys (as path in keyof T), let them be required (remove ? at [path in keyof T]?:), or at least provide an option to toggle it being strict or not.

Motivation

At the moment when defining a Schema, and supplying the first generic to it (RawDocType), it doesn't complain if I miss some keys from the defined type, which is not ideal.

Example

type Item = {
  _id: string;
  name: string;
}

// complains as expected because foo is not in Item
new Schema<Item>({
  _id: String,
  foo: Number
})

// doesn't complain as expected because schema matches type
new Schema<Item>({
  _id: String,
  name: String
})

// doesn't complain, but it should because required property name is not defined
new Schema<Item>({
  _id: String,
})
vkarpov15 commented 1 month ago

This is expected behavior because name can be added via a plugin or Schema.prototype.add() later.

The big issue with making this change would be timestamps:

type Item = {
  _id: string;
  createdAt: Date;
  updatedAt: Date
}

// Valid, schema gets `createdAt` and `updatedAt` properties from `timestamps`
new Schema<Item>({
  _id: String
}, { timestamps: true })

Any suggestions for how to make this work better with TypeScript?