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.