diff --git a/packages/core/src/typings.ts b/packages/core/src/typings.ts index 5e66a3285d94..5e0179e0ebb2 100644 --- a/packages/core/src/typings.ts +++ b/packages/core/src/typings.ts @@ -693,7 +693,11 @@ type Defined = Exclude; // 1. It yes, mark the collection or reference loaded and resolve its inner type recursively (passing suffix). // 2. If no, just return it as-is (scalars will be included, loadables too but not loaded). export type Loaded = T & { - [K in keyof T as IsPrefixed]: LoadedLoadable, Suffix>>; + // this feels more correct, but breaks serialization methods on base entity, see #3865 + // [K in keyof T as IsPrefixed]: LoadedLoadable, Suffix>>; + [K in keyof T]: K extends Prefix + ? LoadedLoadable, Suffix>> + : T[K] }; export interface LoadedReference extends Reference> { diff --git a/tests/types.test.ts b/tests/types.test.ts index 99a0e0c6a4e4..ca387b4c3c67 100644 --- a/tests/types.test.ts +++ b/tests/types.test.ts @@ -1,5 +1,5 @@ -import { wrap } from '@mikro-orm/core'; -import type { IdentifiedReference, Reference, Collection, EntityManager, EntityName, RequiredEntityData } from '@mikro-orm/core'; +import { Ref, wrap } from '@mikro-orm/core'; +import type { BaseEntity, IdentifiedReference, Reference, Collection, EntityManager, EntityName, RequiredEntityData } from '@mikro-orm/core'; import type { Has, IsExact } from 'conditional-type-checks'; import { assert } from 'conditional-type-checks'; import type { ObjectId } from 'bson'; @@ -517,4 +517,17 @@ describe('check typings', () => { assert>(true); }); + test('Loaded type and assignability with extending the ORM BaseEntity (#3865)', async () => { + interface MemberNotification extends BaseEntity { + id: string; + notification?: Ref; + } + + interface Notification extends BaseEntity { + id: string; + } + + const test: MemberNotification = {} as Loaded; + }); + });