Skip to content

Commit

Permalink
fix(core): fix assignability of Loaded type to naked entity
Browse files Browse the repository at this point in the history
Closes #3865
  • Loading branch information
B4nan committed Dec 25, 2022
1 parent 5e793a2 commit e574924
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
6 changes: 5 additions & 1 deletion packages/core/src/typings.ts
Expand Up @@ -693,7 +693,11 @@ type Defined<T> = Exclude<T, null | undefined>;
// 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, L extends string = never> = T & {
[K in keyof T as IsPrefixed<K, L>]: LoadedLoadable<T[K], Loaded<ExtractType<T[K]>, Suffix<L>>>;
// this feels more correct, but breaks serialization methods on base entity, see #3865
// [K in keyof T as IsPrefixed<K, L>]: LoadedLoadable<T[K], Loaded<ExtractType<T[K]>, Suffix<L>>>;
[K in keyof T]: K extends Prefix<L>
? LoadedLoadable<T[K], Loaded<ExtractType<T[K]>, Suffix<L>>>
: T[K]
};

export interface LoadedReference<T> extends Reference<Defined<T>> {
Expand Down
17 changes: 15 additions & 2 deletions 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';
Expand Down Expand Up @@ -517,4 +517,17 @@ describe('check typings', () => {
assert<IsExact<typeof id22, string | undefined>>(true);
});

test('Loaded type and assignability with extending the ORM BaseEntity (#3865)', async () => {
interface MemberNotification extends BaseEntity<MemberNotification, 'id'> {
id: string;
notification?: Ref<Notification>;
}

interface Notification extends BaseEntity<Notification, 'id'> {
id: string;
}

const test: MemberNotification = {} as Loaded<MemberNotification, 'notification'>;
});

});

0 comments on commit e574924

Please sign in to comment.