diff --git a/docs/guides/faq.md b/docs/guides/faq.md index cc8052896..b3bf01c7c 100644 --- a/docs/guides/faq.md +++ b/docs/guides/faq.md @@ -70,3 +70,24 @@ class Cat { _id: mongoose.Types.ObjectId; } ``` + +### Why is `_id` `unknown`? + +It is very likely that your class is just empty, and typescript somehow does not correctly match that and treats it like a generic object. + +Example: + +```ts +class Dummy {} +const DummyModel = getModelForClass(Dummy); +const newDoc = new DummyModel() +newDoc._id; // type: unknown + +class Dummy { + // simple dummy property for types, will complain if actually used + public _dummy: never; +} +const DummyModel = getModelForClass(Dummy); +const newDoc = new DummyModel() +newDoc._id; // type: mongoose.Types.ObjectId +``` diff --git a/src/types.ts b/src/types.ts index 305cc6a28..44ec3c7a9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,10 +11,8 @@ import type { Severity, PropType } from './internal/constants'; * const doc: DocumentType = await NameModel.create({}); * ``` */ -export type DocumentType = (T extends { _id: unknown } - ? mongoose.Document - : mongoose.Document) & - T & +export type DocumentType = mongoose.Document & + mongoose.Require_id & IObjectWithTypegooseFunction; /** * Get the Type of an instance of a SubDocument with Class properties diff --git a/test/tests/types/basicTypegoose.test-d.ts b/test/tests/types/basicTypegoose.test-d.ts index e8a20795a..c7fc8c123 100644 --- a/test/tests/types/basicTypegoose.test-d.ts +++ b/test/tests/types/basicTypegoose.test-d.ts @@ -1,6 +1,6 @@ import { expectType, expectAssignable, expectError } from 'tsd-lite'; import * as typegoose from '../../../src/typegoose'; -import { isDocument, isRefType } from '../../../src/typegoose'; +import { isDocument, isRefType, prop } from '../../../src/typegoose'; import { BeAnObject, IObjectWithTypegooseFunction } from '../../../src/types'; // decorators return type @@ -21,7 +21,10 @@ expectType(typegoose.setGlobalOptions({})); expectType(typegoose.setLogLevel('DEBUG')); // mongoose related function return types -class TestClass {} +class TestClass { + @prop() + public dummy?: string; +} const TestClassModel = typegoose.getModelForClass(TestClass); @@ -166,7 +169,7 @@ async function testDocumentType() { const someNewDoc = new TestClassModel(); expectType< - typegoose.mongoose.Document & + typegoose.mongoose.Document & TestClass & IObjectWithTypegooseFunction & { _id: typegoose.mongoose.Types.ObjectId } >(someNewDoc); @@ -174,7 +177,7 @@ async function testDocumentType() { const someCreatedDoc = await TestClassModel.create(); expectType< - (typegoose.mongoose.Document & + (typegoose.mongoose.Document & TestClass & IObjectWithTypegooseFunction & { _id: typegoose.mongoose.Types.ObjectId })[] >(someCreatedDoc); @@ -182,11 +185,13 @@ async function testDocumentType() { const someFoundDoc = await TestClassModel.findOne(); expectType< - | (typegoose.mongoose.Document & + | (typegoose.mongoose.Document & TestClass & IObjectWithTypegooseFunction & { _id: typegoose.mongoose.Types.ObjectId }) | null >(someFoundDoc); + + expectType(someNewDoc._id); } testDocumentType(); @@ -205,7 +210,7 @@ async function gh732() { const doc = await SomeClassModel.create({ someoptionalProp: 'helloopt', somerequiredProp: 'helloreq' }); expectType< - typegoose.mongoose.Document & + typegoose.mongoose.Document & SomeClass & IObjectWithTypegooseFunction & { _id: typegoose.mongoose.Types.ObjectId } >(doc);