1 year ago

#299589

test-img

SimpleJ

NestJS OpenAPI TS types missing entities

I've got a NestJS app with Mikro-ORM and I'm generating OpenAPI TS types using openapi-typescript for the front-end. I'm using the @ApiProperty decorator to add types to the entity relations, but only one of the two identical relations is being typed correctly in the types output by openapi-typescript.

The entities (note the ingredients and steps fields):

recipe.entity.ts

import { RecipeIngredient } from './recipe-ingredient.entity';
import { RecipeStep } from './recipe-step.entity';

@Entity()
export class Recipe {
  @PrimaryKey()
  id!: number;

  @Property()
  createdAt = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt = new Date();

  @Property()
  name: string;

  @Property()
  @Unique()
  @Index()
  slug: string;

  @ManyToOne({ onDelete: 'cascade' })
  @Index()
  author: User;

  @OneToMany({ mappedBy: 'recipe' })
  @ApiProperty({ type: [RecipeIngredient] })
  ingredients = new Collection<RecipeIngredient>(this);

  @OneToMany({ mappedBy: 'recipe' })
  @ApiProperty({ type: [RecipeStep] })
  steps = new Collection<RecipeStep>(this);

  constructor(name: string, slug: string, author: User) {
    this.name = name;
    this.slug = slug;
    this.author = author;
  }
}

recipe-ingredient.entity.ts

@Entity()
@Unique({ properties: ['recipe', 'index'] })
export class RecipeIngredient {
  @PrimaryKey()
  id!: number;

  @Property()
  createdAt = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt = new Date();

  @Property()
  name: string;

  @ManyToOne({ onDelete: 'cascade', serializer: (value) => value.id })
  @Index()
  recipe: Recipe;

  @Property()
  index: number;

  constructor(recipe: Recipe, name: string, index: number) {
    this.recipe = recipe;
    this.name = name;
    this.index = index;
  }
}

recipe-step.entity.ts

@Entity()
@Unique({ properties: ['recipe', 'index'] })
export class RecipeStep {
  @PrimaryKey()
  id!: number;

  @Property()
  createdAt = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt = new Date();

  @Property({ length: 2000 })
  text: string;

  @ManyToOne({ onDelete: 'cascade', serializer: (value) => value.id })
  @Index()
  recipe: Recipe;

  @Property()
  index: number;

  constructor(recipe: Recipe, text: string, index: number) {
    this.recipe = recipe;
    this.text = text;
    this.index = index;
  }
}

And here is the type produced by running openapi-typescript against the generated OpenAPI schema:

Recipe: {
  /** @default */
  ingredients: { [key: string]: unknown }[];
  /** @default */
  steps: components["schemas"]["RecipeStep"][];
  id: number;
  /** @default 2022-03-16T17:56:07.186Z */
  createdAt: { [key: string]: unknown };
  /** @default 2022-03-16T17:56:07.186Z */
  updatedAt: { [key: string]: unknown };
  name: string;
  slug: string;
  author: components["schemas"]["User"];
}

Why is the steps type being generated correctly but the ingredients type isn't?

typescript

nestjs

openapi

mikro-orm

nestjs-swagger

0 Answers

Your Answer

Accepted video resources