I'm trying to achieve stronger type safety in the following sequelize model definition. I'm not sure how to achieve it properly and I wasn't able to find any answers for this so far. I'm trying to switch from Raw queries to model based ones with the main emphasis of potentially stronger type safety (I know Sequelize is not the best ORM for that purpose but I have a legacy system to work with here)
Current version of sequelize is: "sequelize": "6.29.0",
I have all the Attributes and Instances created for a given Model, but not sure how to connect to dots here in this older integration of the sequelize model definer.
The goal would be being able to do something like this:
const schema = await getOrgenerateSqlSchemaForSyncData(
resolvedDb, USER_SYNC_SCHEMA);
const User = resolvedDb.models[schema.tableName];
const users = await User.findAll();
With users being of type User[]
I have the model definitions in a db/models/User.ts file:
import { Model, Optional } from "sequelize";
import { User } from "@Types/UserTypes";
export interface UserAttributes extends Optional<User, "id"> {}
export interface UserInstance
extends Model<User, UserAttributes>,
User {
createdAt?: Date;
updatedAt?: Date;
}
getOrgenerateSqlSchemaForSyncData does the following:
export const getOrgenerateSqlSchemaForSyncData = async <T extends object>(
db: SqlDatabase,
schema: SyncDataSchema<T>,
) => {
const schemaName = schema.id;
let model = db.models[schemaName];
if (!model) {
const attributes: any = {};
for (const property of schema.properties) {
const attribute: ModelAttributeColumnOptions = {
type: convertSyncDataType(property.type),
primaryKey: property.key === schema.keyProperty,
};
if (typeof property.allowNull !== "undefined") {
attribute.allowNull = property.allowNull;
}
if (typeof property.uniqueKey !== "undefined") {
attribute.unique = property.uniqueKey;
}
if (attribute) {
attributes[property.key] = attribute;
}
}
model = await SqlUtils.syncSqlSchema(db, schemaName, attributes);
}
return model;
};
And here is the syncSqlSchema function I have so far:
export const syncSqlSchema = async <
T extends object,
M extends Model,
TCreationAttributes = M["_attributes"],
>(
database: SqlDatabase,
modelName: string,
attributes: ModelAttributes<M, TCreationAttributes>,
options?: ModelOptions,
): Promise<SqlSchema<T>> => {
const model = database.define(modelName, attributes, {
...options,
freezeTableName: true,
});
await model.sync({
alter: {
drop: false,
},
});
return model;
};
I wonder if I could pass the type of SyncDataSchema<T> down to the syncSqlSchema function so I could do something like
const model = database.define<The type of the sync shchema>(modelName, attributes, {
...options,
freezeTableName: true,
});
to get stronger type safety
The type of the USER_SYNC_SCHEMA is already provided like:
export const USER_SYNC_SCHEMA =
SyncDataUtils.createSyncDataSchema<UserInstance>({
id: "user",
keyProperty: "id",
properties: [
{
So that should be there already, I just wonder how could that be achieved?