I'm trying to extend a class by adding methods and attributes through typescript annotations
My problem is that I cannot set sequelize annotations to the new attribute (comment), so it wont be persisted
Is there any chance of make it work?
Maybe it's not the best place to ask, but I've been researching a lot and couldnt find any answer, and also I found out that TypeORM does support this feature easily so maybe there is a chance of making it work
export function EntityWithComments(target: any): ClassDecorator {
return function (constructor: any) {
target.prototype['comment'] = 'commentValue';
target.prototype['getComment'] = function () {
//...
}
}
}
@EntityWithComments(ConcreteEntity)
@Table
export class ConcreteEntity extends Entity {
@Column
fromDate: Date;
}
export class Entity extends Model<Entity> {
@PrimaryKey
@AutoIncrement
@Column
id: number;
@Column
createdAt: Date;
@Column
updatedAt: Date;
@Column
deletedAt: Date;
}
Hey @CampaUTN what exactly do you want achieve? A comment per column as discussed here https://github.com/sequelize/sequelize/issues/3553 or just a column comment?
Regarding decorators: They won鈥榯 add types to the class you decorated (https://github.com/Microsoft/TypeScript/issues/4881). So best is to go with mixins instead.
Hi! What I want is to persist 'ConcreteEntity' and to have a 'comment' column (just a regular attribute).
I also tried using mixins but they are kind of similar, it returns a function where it's not possible to use annotations
@CampaUTN Ok, here we go:
First, we need some helpers:
// utils.ts
export type MixinType<T> = T extends new(...args: any[]) => infer R ? R : any;
export type Constructor<T = {}> = new (...args: any[]) => T;
Mixins with decorators:
// withComment.ts
import {Column} from "sequelize-typescript";
import {Constructor} from "./utils";
export const withComment = <TBase extends Constructor>(Base: TBase) => {
class WithComment extends Base {
@Column comment: string;
}
return WithComment;
};
```ts
// withLove.ts
import {Column} from "sequelize-typescript";
import {Constructor} from "./utils";
export const withLove =
class WithLove extends Base {
@Column love: string;
}
return WithLove;
};
Definition of our mixed model:
```ts
// User.ts
import {Column, Model, Table} from "sequelize-typescript";
import {withComment} from "../mixins/withComment";
import {withLove} from "../mixins/withLove";
import {MixinType} from "../mixins/utils";
@Table({tableName: 'User'})
class InternalUser extends Model<InternalUser> {
@Column name!: string;
}
export const User = withComment(withLove(InternalUser)); // Creates actual mixed class
export type User = MixinType<typeof User>; // Creates type for mixin
This might also help you: https://blog.mariusschulz.com/2017/05/26/typescript-2-2-mixin-classes
If you still have any questions don't hesitate to ask!
@RobinBuschmann It's amazing and works like a charm. Thank you so much!
Most helpful comment
@CampaUTN Ok, here we go:
First, we need some helpers:
Mixins with decorators:
```ts
// withLove.ts
import {Column} from "sequelize-typescript";
import {Constructor} from "./utils";
export const withLove =(Base: TBase) => {
class WithLove extends Base {
@Column love: string;
}
return WithLove;
};
This might also help you: https://blog.mariusschulz.com/2017/05/26/typescript-2-2-mixin-classes
If you still have any questions don't hesitate to ask!