Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TS2345 sequelize create function

I am creating a sequelize repository and I have an object which extends sequelize model.

I was able to do the following to save the model to the db.

repository.create(myModel) // myModel being an instance of MyModel which extends sequelize model

Now I am getting the following error in typescript:

Argument of type 'MyModel' is not assignable to parameter of type 'CreationAttributes<MyModel>'.
  Type 'MyModel' is not assignable to type 'Omit<any, string>'.
    Index signature for type 'number' is missing in type 'MyModel'.ts(2345)

I was doing some searching and a suggestion was to add to MyModel:

[key: number]: number;

When I do that the error is changed to the following:

Argument of type 'MyModel' is not assignable to parameter of type 'CreationAttributes<MyModel>'.
  Type 'MyModel' is not assignable to type 'Omit<any, string>'.
    Index signature for type 'symbol' is missing in type 'MyModel'.ts(2345)

I can get around the error by changing the call to create:

repository.create({...myModel})

Can anyone point me to documentation about ts(2345) what it is, perhaps how to ignore it. Or even solve the issue the correct way?

Using the spread operator, to me seems a bit messy, but if that is the correct solution that is fine.

Model definition:

import {
  Column, DataType, ForeignKey, Model, Sequelize, Table,
} from 'sequelize-typescript';
import MediaResource from './media_resource';
import User from './users';

@Table({
  tableName: 'videos',
  timestamps: true,
  version: true,
})
export default class Video extends Model {
  @Column({
    primaryKey: true,
    autoIncrement: true,
    type: DataType.INTEGER,
    defaultValue: Sequelize.literal("nextval('videos_id_seq'::regclass)"),
  })
  id?: number;

  @ForeignKey(() => MediaResource)
  @Column({
    field: 'media_resource_id',
    allowNull: false,
    type: DataType.INTEGER,
  })
  mediaResourceId?: number;

  @Column({
    allowNull: false,
    type: DataType.STRING(191),
  })
  title?: string;

  @Column({
    allowNull: false,
    type: DataType.STRING(2000),
  })
  url?: string;

  @Column({
    allowNull: true,
    type: DataType.STRING(512),
  })
  description?: string;

  @Column({
    allowNull: false,
    type: DataType.BOOLEAN,
  })
  is_3d?: boolean;

  @Column({
    allowNull: false,
    type: DataType.BOOLEAN,
  })
  is_360?: boolean;

  @ForeignKey(() => User)
  @Column({
    field: 'user_id',
    allowNull: false,
    type: DataType.INTEGER,
  })
  userId?: number;

  @Column({
    field: 'created_at',
    allowNull: false,
    type: DataType.DATE,
  })
  createdAt?: Date;

  @Column({
    field: 'updated_at',
    allowNull: false,
    type: DataType.DATE,
  })
  updatedAt?: Date;
}

Repository create signiture:

const db = DB.getInstance();
const videosRepository = db.getRepository(Video);
const transaction = await db.transaction();

try {
  const saved = await videosRepository.create({ ...video }, { transaction });
await transaction.commit();
return saved;
} catch (err) {
  await transaction.rollback();
  if (err instanceof Error) logger.error(err.message);
  throw new InternalServerError();
}

We have a sequelize singleton which is what db is, the video object is created from an express request body.

Also this used to work, I could add a ts-ignore comment and it will work.

sequelize: 6.15.1 sequelize-typescript: 2.1.2 typescript: 4.5.5

like image 970
Mark Howard Avatar asked Aug 08 '26 08:08

Mark Howard


1 Answers

So I've come across 2 solutions to this problem, the first is as outlined above:

repository.create({ ...myModel })

And the second is:

repository.create(myModel as any)

like image 120
Mark Howard Avatar answered Aug 10 '26 00:08

Mark Howard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!