Skip to content

Commit 502ec4b

Browse files
authored
Merge pull request #13990 from Automattic/vkarpov15/gh-13897
types(models): make all properties to Model constructor optional
2 parents 572e018 + d3d2ec4 commit 502ec4b

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

docs/migrating_to_8.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ If you're still on Mongoose 6.x or earlier, please read the [Mongoose 6.x to 7.x
2525
* [`create()` waits until all saves are done before throwing any error](#create-waits-until-all-saves-are-done-before-throwing-any-error)
2626
* [`Model.validate()` returns copy of object](#model-validate-returns-copy-of-object)
2727
* [Allow `null` For Optional Fields in TypeScript](#allow-null-for-optional-fields-in-typescript)
28+
* [Model constructor properties are all optional in TypeScript](#model-constructor-properties-are-all-optional-in-typescript)
2829
* [Infer `distinct()` return types from schema](#infer-distinct-return-types-from-schema)
2930

3031
<h2 id="removed-rawresult-option-for-findoneandupdate"><a href="#removed-rawresult-option-for-findoneandupdate">Removed <code>rawResult</code> option for <code>findOneAndUpdate()</code></a></h2>
@@ -247,6 +248,39 @@ const doc = new TestModel();
247248
doc.name;
248249
```
249250

251+
<h2 id="model-constructor-properties-are-all-optional-in-typescript"><a href="#model-constructor-properties-are-all-optional-in-typescript">Model constructor properties are all optional in TypeScript</a></h2>
252+
253+
In Mongoose 8, no properties are required on model constructors by default.
254+
255+
```ts
256+
import {Schema, model, Model} from 'mongoose';
257+
258+
interface IDocument {
259+
name: string;
260+
createdAt: Date;
261+
updatedAt: Date;
262+
}
263+
264+
const documentSchema = new Schema<IDocument>(
265+
{ name: { type: String, required: true } },
266+
{ timestamps: true }
267+
);
268+
269+
const TestModel = model<IDocument>('Document', documentSchema);
270+
271+
// Would throw a compile error in Mongoose 7, compiles in Mongoose 8
272+
const newDoc = new TestModel({
273+
name: 'Foo'
274+
});
275+
276+
// Explicitly pass generic param to constructor to specify the expected
277+
// type of the model constructor param. The following will cause TS
278+
// to complain about missing `createdAt` and `updatedAt` in Mongoose 8.
279+
const newDoc2 = new TestModel<IDocument>({
280+
name: 'Foo'
281+
});
282+
```
283+
250284
<h2 id="infer-distinct-return-types-from-schema"><a href="#infer-distinct-return-types-from-schema">Infer <code>distinct()</code> return types from schema</a></h2>
251285

252286
```ts

test/types/models.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,3 +751,23 @@ function gh13957() {
751751
const repository = new RepositoryBase<ITest>(TestModel);
752752
expectType<Promise<ITest[]>>(repository.insertMany([{ name: 'test' }]));
753753
}
754+
755+
function gh13897() {
756+
interface IDocument {
757+
name: string;
758+
createdAt: Date;
759+
updatedAt: Date;
760+
}
761+
762+
const documentSchema = new Schema<IDocument>({
763+
name: { type: String, required: true }
764+
},
765+
{
766+
timestamps: true
767+
});
768+
769+
const Document = model<IDocument>('Document', documentSchema);
770+
const doc = new Document({ name: 'foo' });
771+
expectType<Date>(doc.createdAt);
772+
expectError(new Document<IDocument>({ name: 'foo' }));
773+
}

types/models.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ declare module 'mongoose' {
158158
AcceptsDiscriminator,
159159
IndexManager,
160160
SessionStarter {
161-
new <DocType = TRawDocType>(doc?: DocType, fields?: any | null, options?: boolean | AnyObject): THydratedDocumentType;
161+
new <DocType = Partial<TRawDocType>>(doc?: DocType, fields?: any | null, options?: boolean | AnyObject): THydratedDocumentType;
162162

163163
aggregate<R = any>(pipeline?: PipelineStage[], options?: AggregateOptions): Aggregate<Array<R>>;
164164
aggregate<R = any>(pipeline: PipelineStage[]): Aggregate<Array<R>>;

0 commit comments

Comments
 (0)