Typegoose models problems with ObjectId in array

113 Views Asked by At

I have a few models that were working fine for a few months. model1.ts - it has some props that are objects and are declared separately for reusing purposes and for avoiding mixed types warning:

import { modelOptions, prop, Ref, mongoose } from "@typegoose/typegoose";
import { Prop1, Prop2, Prop3 } from "../interfaces/modelInterfaces";
...
export class Model1 {
  @prop({ auto: true })
  public _id!: mongoose.Schema.Types.ObjectId;
  @prop()
  public someName: string;
  @prop()
  public someType: string;
  ...
  @prop({ type: Prop1 })
  public prop1: Prop1;
  @prop({ type: Prop2 })
  public prop2: Prop2;
}

those Props are described like there: modelInterfaces.ts

import { prop } from "@typegoose/typegoose";
export class Prop1 {
  @prop()
  public original: string;
  @prop()
  public thumbnail1?: string;
  @prop()
  public thumbnail2?: string;
  @prop()
  public thumbnail3?: string;
}
export class Prop2 {
  @prop()
  routingNumber: string;
  @prop()
  accountNumber: string;
}
export class Prop3 {
  @prop({ enum: ExpenseCoverage })
  public coverage: ExpenseCoverage;
  @prop()
  public percent?: number;
  @prop()
  public nonProfit: boolean;
  @prop()
  public EIN?: string;
}
...

model2.ts:

import { Ref, prop, modelOptions, mongoose } from "@typegoose/typegoose";
import { Model1 } from "../models/model1";
...
export class Model2 {
  @prop({ auto: true })
  public _id!: mongoose.Schema.Types.ObjectId;

  @prop({ required: true, ref: () => Model1, refPath: "model1ID" })
  public model1ID!: Ref<Model1>;

  @prop({ required: true })
  public someProp1!: string;

  @prop({ required: true })
  public someProp2!: number;

  @prop({ required: true, default: 0 })
  public someProp3: number;
  ...
}

All of it was working for a half a year until now I need to create such kind of model:

model3.ts

import { modelOptions, prop, Ref, mongoose, index } from "@typegoose/typegoose";
import { Model1 } from "../models/model1";
import { ProblematicProp } from "../interfaces/modelInterfaces";
...
export class Model3 {
  @prop({ auto: true })
  public _id!: mongoose.Schema.Types.ObjectId;

  @prop({ required: true, ref: () => Model1, refPath: "model1ID" })
  public model1ID!: Ref<Model1>;

  @prop({ required: true })
  public someName!: string;

  @prop()
  public notes: string;

  @prop({ required: true })
  public troublesProp!: ProblematicProp[];

  @prop({ required: true })
  public quantity!: number;
  ...
}

and finally new ProblematicProp is declared in modelInterfaces.ts

...
export class ProblematicProp {
  @prop({ required: true, ref: () => Model2, refPath: "model2ID" })
  public model2ID!: Ref<Model2>;

  @prop()
  public quantity: number;
}

Now very first getModelForClass(Model1) which is not even related to model3 fails with error:

error: "Model1.prop1"'s Type is invalid! Type is: "undefined" [E009]: 
        httpStatusCode::500
InvalidTypeError: "Model1.prop1"'s Type is invalid! Type is: "undefined" [E009]

Prop1 is not event related to that new model3 and its ProblematicProp! BUT when I remove ObjectId (model2ID) prop from ProblematicProp the error dissappears. So it's something about strange cases of objectIds and types in model declarations. Also, I have fount this kind of workaround: I got rid of modelInterfaces and declared its components inside models. For example model1 looks like this:

export class Model1 {
  @prop({ auto: true })
  public _id!: mongoose.Schema.Types.ObjectId;
  @prop()
  public someName: string;
  @prop()
  public someType: string;
  ...
  /* @prop({ type: Prop1 })
  public prop1: Prop1;*/
  @prop()
  public prop1: {
    public original: string;
    public thumbnail1?: string;
    public thumbnail2?: string;
    public thumbnail3?: string;
  };
  ...
}

It works but now I got a tons of mixed types errors. My question here is why it is happening? Where was my original mistake and is there a way to keep Props and not to have mixed types and use allowMixed: Severity.ALLOW in @modelOptions?

Thank you for your patients at reading this.

0

There are 0 best solutions below