# Anyone worked with sequelize-typescript or similar?

**URL:** <https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671>\
**Category:** Help me!\
**Tags:** typescript\
**Created:** [January 20, 2021, 10:17am UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671 "2021-01-20T10:17:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kll](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/kll/32/7091_2.png) [@kll](https://community.forestadmin.com/u/kll)\
**Post date:** [January 20, 2021, 10:17am UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671/1 "2021-01-20T10:17:33Z")

</div>

I have an existing medium-sized project on ForestAdmin across more than one database.

I’d really like to avoid defining both static interfaces and runtime schema using Sequelize with the suggested approach on the Woodshop.

I’m looking at projects like [GitHub - RobinBuschmann/sequelize-typescript: Decorators and some other features for sequelize](https://github.com/RobinBuschmann/sequelize-typescript), which would allow us to define our interfaces and schema at once.

Has anyone worked with such a project and ForestAdmin?

---

<div class="post-metadata">

**Author:** ![anon62739609](https://avatars.discourse-cdn.com/v4/letter/a/c2a13f/32.png) [@anon62739609](https://community.forestadmin.com/u/anon62739609)\
**Post date:** [January 25, 2021, 10:49am UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671/2 "2021-01-25T10:49:33Z")

</div>

Hi @kll and welcome in our community 🍾 !

Sorry but I did not understood what you meant 😅  
What are you talking about when you speak about static interfaces ?  
Same question for runtime schema ?

---

<div class="post-metadata">

**Author:** ![kll](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/kll/32/7091_2.png) [@kll](https://community.forestadmin.com/u/kll)\
**Post date:** [January 25, 2021, 11:09am UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671/3 "2021-01-25T11:09:59Z")

</div>

Hey @anon62739609 !

Using the example from the Woodshop, here’s the static interface:

```javascript
import { Model } from "sequelize";

export default class Users extends Model {
    public id!: number;
    public firstname!: string;
    public lastname!: string;
    public readonly createdAt: Date;
    public readonly updatedAt: Date;
}

```

And here’s the runtime schema that is actually used:

```javascript
import Users from '../interfaces/users';

export default (sequelize, DataTypes) => {
  Users.init(
    {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
      },
      firstname: {
        type: new DataTypes.STRING(128),
        allowNull: false
      },
      lastname: {
        type: new DataTypes.STRING(128),
        allowNull: false
      }
    },{
        tableName: "users",
        modelName: 'users',
        sequelize,
    }
  );

  return Users;
}

```

I’ve had to define twice every property and every type.  
I’m unsure if the `type` field of every model is safely typed of if I can define one of the interface property as `number` and the runtime property as `new DataTypes.STRING(128)`.

Using a project such as the one linked in OP would allow to bypass this duality (example from their README):

```javascript
@Table
class Person extends Model {

  @Column
  name: string;

  @Column
  birthday: Date;

  @HasMany(() => Hobby)
  hobbies: Hobby[];
}

```

PS: Thanks for the welcome =)

---

<div class="post-metadata">

**Author:** ![anon62739609](https://avatars.discourse-cdn.com/v4/letter/a/c2a13f/32.png) [@anon62739609](https://community.forestadmin.com/u/anon62739609)\
**Post date:** [January 25, 2021, 1:18pm UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671/4 "2021-01-25T13:18:57Z")

</div>

Oh okey !  
Well we did not tried it as far as I know, but you can try to use it, I don’t think you’ll have issue with ForestAdmin using this library 😉

---

<div class="post-metadata">

**Author:** ![anon20071947](https://avatars.discourse-cdn.com/v4/letter/a/b5a626/32.png) [@anon20071947](https://community.forestadmin.com/u/anon20071947)\
**Post date:** [January 25, 2021, 2:14pm UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671/5 "2021-01-25T14:14:17Z")

</div>

For native CRUD, Forest Admin will still use plain ‘old’ sequelize queries under the hood even if your models are declared using annotations for type safe attributes.

The OP reads

> ### Build and create
> 
> Instantiation and inserts can be achieved in the good old sequelize way
> 
> const person = Person.build({name: ‘bob’, age: 99}); person.save(); Person.create({name: ‘bob’, age: 99});

and

> ### Find and update
> 
> Finding and updating entries does also work like using native sequelize. So see sequelize [docs](https://docs.sequelizejs.com/manual/tutorial/models-usage.html) for more details.
> 
> Person .findOne() .then(person =\> { person.age = 100; return person.save(); }); Person .update({ name: ‘bobby’ }, {where: {id: 1}}) .then(() =\> { });

It looks like you should be on the clear but I don’t know if things won’t break at some point for you 🙂

Let us know how it goes if you try it!

---

<div class="post-metadata">

**Author:** ![kll](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/kll/32/7091_2.png) [@kll](https://community.forestadmin.com/u/kll)\
**Post date:** [October 28, 2021, 1:44pm UTC](https://community.forestadmin.com/t/anyone-worked-with-sequelize-typescript-or-similar/1671/6 "2021-10-28T13:44:16Z")

</div>

So, we indeed tried this. It’s in production now =)

Here is what our models look like:

```javascript
@Table({ tableName: 'ChatMessages', schema: process.env.DATABASE_SCHEMA })
export default class ChatMessage extends Model {
  @PrimaryKey
  @Column(DataType.UUID)
  Id: string

  @CreatedAt
  CreatedAt: Date

  @UpdatedAt
  UpdatedAt: Date

  @Column
  Body: string

  @BelongsTo(() => User, 'UserId')
  Author: User

  @BelongsTo(() => Chatroom, 'ChatroomId')
  Chatroom: Chatroom
}

```

This makes creating, updating and working with the models much, much easier now.

The main drawback is that many API endpoints for forest like record getters and smart field definitions still default to `any` for types, without taking into account the actual model used.

For example:

```javascript
import { collection } from 'forest-express-sequelize'

collection('User', { // magic string so we're not starting well there for any typing
  actions: [],
  fields: [
    {
      field: 'FullName',
      type: 'String',
      get: (user) => { // yep, user is any
        return user.FirstName + ' ' + user.LastName // no type check
      }
    }
  ],
  segments: []
})

```

Another from your TypeScript definitions:

```javascript
export class RecordCreator<M extends Sequelize.Model> extends AbstractRecordTool<M> {
  // ouch. Not using _creationAttributes means
  // we don't get any help when creating a record
  create(record: Record<string, unknown>): Promise<M>;
}

```

Of course we can still type by force:

```javascript
collection('User', { // magic string
  actions: [],
  fields: [
    {
      field: 'FullName',
      type: 'String',
      get: (user: User) => { // user is a User
        return user.FirstName + ' ' + user.LastName // type checked!
      }
    },
// ...

```

Which makes me think we could go even further, like so:

```javascript
collection(User, { // BAM, pass the model constructor!
  actions: [],
  fields: [
    {
      field: 'FullName',
      type: 'String',
      get: (user) => { // user is instance of the model
        return user.FirstName + ' ' + user.LastName // type checks for everyone
      }
    },
// ...

```

But it breaks native Forest project scaffolds by asking of developers that they export their models instead of blob-importing all of them.

We’ve actually been exporting all our models since switching the project to TypeScript and typescript-sequelize, so we’ve been tempted to write typed wrappers around Forest APIs…

Is there anything like this in your roadmap?
