I don’t even know where to begin or what to look for with this one.
I’m upgrading an old React, Node, Express full-stack application, and one of the steps I’m taking is adding TypeScript. The project still uses WebPack and Babel, and I’ve upgraded those, but I don’t have the knowledge or time to replace it with something else. In the process of the upgrade, I’ve read that using the babel-loader to transform TypeScript is preferable over ts-loader. That’s fine, as long as it works. However, I’m also trying to upgrade Sequelize and implement sequelize-typescript for more declarative models. Trying to compile it though, I get a strange error I don’t understand, as I’ve otherwise followed all the directions I’ve read.
(ETA: This does work if I’m using ts-loader, so it’s something specific to Babel and/or its configuration. It seems like there should be a way to get babel-loader to support the same compilation as ts-loader if people are recommending it over ts-loader.)
The error is:
ERROR in ./lib/models/payment-typed.ts
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/chris/code/ps-client/lib/models/payment-typed.ts: Fields with the 'declare' modifier cannot be initialized here, but only in the constructor
12 | })
13 | export class PaymentTyped extends Model {
> 14 | @Column({
| ^
15 | type: DataTypes.INTEGER,
16 | allowNull: false,
17 | autoIncrement: true,
at File.buildCodeFrameError (/Users/chris/code/ps-client/node_modules/@babel/core/lib/transformation/file/file.js:195:12)
...
The code it’s trying to compile is:
import { Column, Model, Table } from 'sequelize-typescript'
import { DataTypes } from 'sequelize'
@Table({
createdAt: 'CreatedOn',
modelName: 'Payment',
timestamps: true,
freezeTableName: true,
tableName: 'Payment',
updatedAt: 'UpdatedOn',
hasTrigger: true
})
export class PaymentTyped extends Model {
@Column({
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
})
declare ID: number
...
And the portion of the config that I think is relevant is:
...
export const BabelPresets = (envPreset) => [
['@babel/preset-env', envPreset],
[
'@babel/preset-react',
{
runtime: 'automatic'
}
],
[
'@babel/preset-typescript',
{
onlyRemoveTypeImports: true,
allowNamespaces: true,
dts: true,
allowDeclareFields: true
}
]
]
export const JavaScriptRules = (envPreset) => ({
test: /.(js|ts)x?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: BabelPresets(envPreset),
plugins: [
// https://babeljs.io/docs/babel-plugin-transform-typescript#typescript-compiler-options
'babel-plugin-transform-typescript-metadata',
['@babel/plugin-proposal-decorators', { version: '2023-11' }],
[
'babel-plugin-typescript-to-proptypes',
{ mapUnknownReferenceTypesToAny: true, strict: true }
]
]
}
}
})
...
I don’t even really know how to debug or research this. Google searches come up with seemingly completely unrelated and irrelevant stuff.
What can I change in my configuration or code to make this or something like this work?
Thanks
In your code, you are trying to use a property decorator(@column) on a field declared with declare. In Typescript, declare fields can only be initialized in the constructor, which is why you’re seeing the error.
Solution:
Remove the declare modifier, and just define the property normally:
@Column({
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
})
ID: number
3