Encountering an issue when combining sequelize-typescript with babel-preset-typescript. The challenge lies in retrieving columns using Object.defineProperty(), as existing properties are being skipped, leading to inconsistencies. While the regular typescript implementation works seamlessly with Sequelize†, switching to babel-typescript retains the unwanted properties.
Inquiry: How can I configure Babel to correctly ignore these unwanted properties?
Babel configurations (babel.config.js)
I've experimented with two different Babel configurations – one encompassing all desired features and another requiring explicit definitions.
Comprehensive definition
module.exports = {
plugins: [
[
"@babel/plugin-transform-runtime",
{
regenerator: true,
},
],
"babel-plugin-inline-import",
"babel-plugin-transform-typescript-metadata",
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/proposal-class-properties", { loose: true }],
"@babel/proposal-object-rest-spread",
"@babel/plugin-proposal-optional-chaining",
[
"module-resolver",
{
alias: {
"~": "./src",
},
},
],
],
presets: ["@babel/preset-env", "@babel/typescript"],
};
Condensed explicit definition
module.exports = {
plugins: [
["@babel/proposal-decorators", { legacy: true }],
["@babel/proposal-class-properties", { loose: true }],
"@babel/proposal-async-generator-functions",
"@babel/proposal-object-rest-spread",
"@babel/plugin-transform-runtime",
],
presets: ["@babel/preset-env", "@babel/typescript"],
};
Context & specifics
You can find a standard non-babel example for testing here, where the branches babel_build and babel_explicit showcase different babel implementations.
The essence of defining a table involves simply adding decorators to the code:
import { Table, Column, Model } from 'sequelize-typescript'
@Table
class Person extends Model {
@Column
name: string
@Column
birthday: Date
}
The issue arises when attempting to retrieve data through:
const p = await Person.findOne({ name: "John Doe" })
console.log(p)
resulting in:
Person {
dataValues: {
id: 1,
name: "John Doe",
birthday: null
},
_previousDataValues: {
id: 1,
name: "John Doe",
birthday: null
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [
'id',
'name',
'birthday'
]
},
isNewRecord: false,
name: undefined,
birthday: undefined,
}
highlighting the issue with undefined
values in the last rows.
Update - utilizing declare
Exploring further solutions suggests leveraging the declare
keyword, although practical implementation proves challenging.
import { Table, Column, Model } from 'sequelize-typescript'
@Table
class Person extends Model {
@Column
declare name: string
@Column
declare birthday: Date
}
accompanied by the following configuration:
module.exports = {
plugins: [
["@babel/plugin-transform-typescript", { allowDeclareFields: true }],
[
"@babel/plugin-transform-runtime",
{
regenerator: true,
},
],
"babel-plugin-transform-typescript-metadata",
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/proposal-class-properties", { loose: true }],
[
"module-resolver",
{
alias: {
"~": "./src",
},
},
],
],
presets: ["@babel/preset-env"],
};
Despite efforts, the problem persists, indicating that while declare
may align more closely with the intended use, it falls short in practice.
† this discrepancy likely transcends the additions made by sequelize-typescript