Reputation: 46218
What is the correct way of using this.getDataValue
in a getter function for a Sequelize model when using TypeScript?
This is the error I'm getting:
Property 'getDataValue' does not exist on type 'string | DataTypeAbstract | DefineAttributeColumnOptions'.
Property 'getDataValue' does not exist on type 'string'.
My model definition:
import * as Sequelize from 'sequelize';
import sequelize from '../db-connection';
export interface IUserAttributes {
date_of_birth: Date;
name: string;
}
export interface IUserInstance extends Sequelize.Instance<IUserAttributes> {
date_of_birth: Date;
name: string;
}
const User = sequelize.define<IUserAttributes, IUserInstance>('user', {
name: {
type: Sequelize.STRING,
validate: {
notEmpty: true,
},
},
date_of_birth: {
get(): Date {
return new Date(this.getDataValue('date_of_birth'));
},
type: Sequelize.DATEONLY,
validate: {
isDate: true,
notEmpty: true,
},
},
});
export default User;
Upvotes: 5
Views: 10245
Reputation: 102277
For "sequelize": "^5.21.3"
, "typescript": "^3.7.5"
and define the sequelize model using TypeScript class based style.
index.ts
:
import { sequelize } from '../../db';
import Sequelize, { Model } from 'sequelize';
class User extends Model {
public date_of_birth!: Date;
public name!: string;
}
User.init(
{
name: {
type: Sequelize.STRING,
validate: {
notEmpty: true,
},
},
date_of_birth: {
get(this: User): Date {
return new Date(this.getDataValue('date_of_birth'));
},
type: Sequelize.DATEONLY,
validate: {
isDate: true,
notEmpty: true,
},
},
},
{ sequelize, modelName: 'user' },
);
Cast this
type to User
class will get rid of the error. Don't forget to declare the properties in the User
class.
Upvotes: 3
Reputation: 24785
Here is a working example> It casts the underlying TEXT value in column data to a new JSONB type column called payload:
import {DataTypes, Model, Sequelize} from 'sequelize';
export class Book extends Model {
public id!: number;
public name!: string;
public payload!: any;
private data!: string;
}
export const initBook = (sequelize: Sequelize) => {
Book.init(
{
id: {
type: DataTypes.INTEGER,
primaryKey: true
},
name: {
type: DataTypes.STRING(100),
primaryKey: false
},
data: {
type: DataTypes.TEXT,
primaryKey: false
},
payload: {
type: DataTypes.JSONB,
allowNull: false,
field: 'data',
get(this: any) {
const j = this.getDataValue('payload');
return JSON.parse(j);
}
}
},
{
tableName: 'book',
sequelize // this bit is important
}
);
};
export default {Book, initBook};
Upvotes: 0
Reputation: 249656
You need to specify the type for this
inside the getter function
const User = sequelize.define<IUserAttributes, IUserInstance>('user', {
name: {
type: Sequelize.STRING,
validate: {
notEmpty: true,
},
},
date_of_birth: {
get(this: IUserInstance): Date {
return new Date(this.getDataValue('date_of_birth'));
},
type: Sequelize.DATEONLY,
validate: {
isDate: true,
notEmpty: true,
},
},
});
Note The this
argument will not get emitted to JS it is just for the benefit of the typescript compiler.
Upvotes: 9