objection.js
objection.js copied to clipboard
What is the best way to type a model with relations?
I have a model like this, with the corresponding interface:
export default class CIProject extends BaseEntity implements ICIProject {
static tableName = TableNames.CI_PROJECT;
id: number;
projectNumber?: number;
projectName: string;
owner: string;
status: number;
projectDueDate: Dayjs;
completedDate?: Dayjs;
createdAt: Dayjs;
static relationMappings = () => {
return {
tasksRelationship: {
relation: Model.HasManyRelation,
modelClass: CIProjectTask,
join: {
from: `${TableNames.CI_PROJECT}.id`,
to: `${TableNames.CI_PROJECT_TASK}.project_id`,
},
},
};
};
}
export interface ICIProject {
id: number;
projectNumber?: number;
projectName: string;
owner: string;
status: number;
projectDueDate: Dayjs;
completedDate?: Dayjs;
createdAt: Dayjs;
tasksRelationship?: ICIProjectTask[];
}
For tasksRelationship, I'd like to make it required when returning a query with withGraphJoined("tasksRelationship"), but I'd have to typecast the result to unknown first:
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
const res = (await CIProject.query().withGraphJoined(
"tasksRelationship"
)) as unknown as Array<WithRequired<ICIProject, "tasksRelationship">>;
If I don't typecast it to unknown first, it gives me the following error: Property 'tasksRelationship' is missing in type 'CIProject' but required in type '{ tasksRelationship: ICIProjectTask[]; }'.
Is there a better way of doing this, so I don't have to typecast it to unknown first?