node.jstypescriptpostgresqlmikro-ormpostgresql-14

Issue in creating a class instance using mikro-orm and typescript and inserting into postgresql database


I'm trying to code along to this React GraphQL TypeScript tutorial

The project uses MikroOrm to communicate with a PostgreSQL database.

Goal: To create an instance of post and insert it into the database.

Currently I'm at minute 19.53 and I'm stuck with the following error which does not appear in the video, I'm not sure why.

Post.ts file:

@Entity() //correspond to database table.
export class Post {
    @PrimaryKey()
    id!: number;

    @Property({ type: 'date'}) //denote database column, without it its just a class attribute
    createdAt = new Date();

    @Property({ type: 'date', onUpdate: () => new Date() })
    updatedAt = new Date();

    @Property({type: 'text'})
    title!: string;
}

Index.ts file:

const main = async () => {
    const orm = await MikroORM.init(microConfig);
    const post = orm.em.create(Post, {title: "my first post" }); //create instance of post
    await orm.em.persistAndFlush(post); //insert into database
}

The line in Index.ts is throwing me an error:

const post = orm.em.create(Post, {title: "my first post" });
Argument of type '{ title: string; }' is not assignable to parameter of type 'RequiredEntityData<Post>'.
  Type '{ title: string; }' is missing the following properties from type '{ createdAt: EntityDataItem<Date>; updatedAt: EntityDataItem<Date>; title: EntityDataItem<string>;

Solution

  • v6 adds a new way to deal with this, the Opt type, which you can simply intersect in your property definition. This is helpful mainly for base entities so you dont have to deal with generics for the OptionalProps symbol.

    https://mikro-orm.io/docs/next/guide/relationships#alternative-approach-with-opt-type

    @Entity()
    export class Post {
        @PrimaryKey()
        id!: number;
    
        @Property()
        createdAt: Date & Opt = new Date();
    
        @Property({ onUpdate: () => new Date() })
        updatedAt: Date & Opt = new Date();
    
        @Property({ type: 'text' })
        title!: string;
    }
    

    You need to mark properties that have initializer via OptionalProps symbol to make them optional for the em.create() method. Also instead of explicit type option you can just specify the type explicitly (inference won't work with reflect-metadata).

    https://mikro-orm.io/docs/property-validation#properties-with-default-value

    Here is an entity definition that should work fine:

    @Entity()
    export class Post {
        [OptionalProps]?: 'createdAt' | 'updatedAt';
    
        @PrimaryKey()
        id!: number;
    
        @Property()
        createdAt: Date = new Date();
    
        @Property({ onUpdate: () => new Date() })
        updatedAt: Date = new Date();
    
        @Property({ type: 'text' })
        title!: string;
    }