4

I am trying to work out how to define additional optional properties.

import { Entity, PrimaryKey, Property, OptionalProps } from '@mikro-orm/core';

@Entity()
export abstract class BaseEntity {
  [OptionalProps]?: 'createdAt';

  @PrimaryKey()
  id: number;

  @Property()
  createdAt: Date = new Date();

}

@Entity()
export class EntityA extends BaseEntity {
  [OptionalProps]?: 'isAnotherProperty'; // This is the bit I cannot figure out

  @Property()
  isAnotherProperty: boolean = false;

}

With the above TypeScript throws an error:

Property '[OptionalProps]' in type 'EntityA' is not assignable to the same property in base type 'BaseEntity'.

Basically my BaseEntity has optional properties, as does EntityA. I could remove [OptionalProps]?: from BaseEntity and have [OptionalProps]?: 'createdAt' | 'isAnotherProperty'; in EntityA, but many of my entities don't require any additional optional properties beyond createdAt so I prefer not to have to duplicate [OptionalProps]?: 'createdAt'; in every entity class if I could just 'extend' it where I need to.

Is it at all possible to either append to or override [OptionalProps]?

FireLeopard
  • 314
  • 4
  • 18

1 Answers1

7

Probably the cleanest approach is via type argument on the base entity:

import { Entity, PrimaryKey, Property, OptionalProps } from '@mikro-orm/core';

@Entity()
export abstract class BaseEntity<Optional = never> {

  [OptionalProps]?: Optional | 'createdAt';

  @PrimaryKey()
  id: number;

  @Property()
  createdAt: Date = new Date();

}

@Entity()
export class EntityA extends BaseEntity<'isAnotherProperty'> {

  @Property()
  isAnotherProperty: boolean = false;

}
Martin Adámek
  • 16,771
  • 5
  • 45
  • 64
  • I tried both, the first option worked, but with the second option I get `'Omit' only refers to a type, but is being used as a value here.`. I have opted for the first as that seems to solve my problem. Thanks – FireLeopard Feb 07 '22 at 10:49
  • You forgot to use `typeof` there, the second approach works also just fine. You can ses it being used in the tests: https://github.com/mikro-orm/mikro-orm/blob/master/tests/entities-schema/Test4.ts edit: or maybe it does not work with classes but just interfaces, not sure now. I would still stuggest the first approach as its much cleaner. – Martin Adámek Feb 07 '22 at 10:50
  • @MartinAdámek I assume there were two options in the answer, but now it's only one, right? And how to properly make the `O` generic type optional? Will it be `export abstract class BaseEntity`? – evenfrost Dec 15 '22 at 12:37
  • Yeah my initial idea wasn't working :] `never` should do the job, as it gets removed from union types, e.g. `number | string | never` simplifies to `number | string`. – Martin Adámek Dec 15 '22 at 13:11