Decorators support inconsistent with Typescript
See original GitHub issueBug Report
I was trying to port build pipeline (webpack) from ts-loader to babel-loader. I am using decorator (for redux action types) implementation bellow.
Current Behavior My input code works just fine with typescript. However using babel, prototype in actionClass in my decorator is undefined. I also tried various modifications (omit prototype and set type directly on actionClass) but all failed. I was simply unable to set type on the base class with decorator.
// Babel console.log(actionClass);
Descriptor {kind: "class", elements: Array(0), Symbol(Symbol.toStringTag): "Descriptor"}
Input Code
abstract class Action {
public type: string;
constructor() {
this.type = this.type;
}
}
export interface ActionClass<T extends Action> {
prototype: T;
}
export function typeName(name: string): <T extends Action>(actionClass: ActionClass<T>) => void {
return actionClass => {
actionClass.prototype.type = name;
};
}
// Usage :
export interface TestActionPayload {
sample: string;
}
@typeName('TEST_ACTION')
export class TestAction extends Action {
constructor(public payload: TestActionPayload) {
super(payload);
}
}
Expected behavior/code It is partly unclear to me if this is a bug, or problem on my end. However, one way or another, I am expecting to be able to set properties on base class with decorators. Currently I can’t.
// Typescript console.log(actionClass);
ƒ TestAction(payload) {
var _this = _super.call(this, payload) || this;
_this.payload = payload;
return _this;
}
Babel Configuration (.babelrc, package.json, cli command)
options: {
cacheDirectory: true,
babelrc: false,
presets: [
[
"@babel/preset-env",
{ targets: { browsers: "last 2 versions" } } // or whatever your project requires
],
"@babel/preset-typescript",
"@babel/preset-react"
],
plugins: [
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
"@babel/plugin-syntax-dynamic-import",
"react-hot-loader/babel"
]
}
Environment
- Babel version(s): [7.1.2]
- Node/npm version: [Node 9.5.0/npm 6.4.1]
- OS: [Windows 10]
- Monorepo [no]
- How you are using Babel: [
loader
]
Possible Solution
Additional context/Screenshots Add any other context about the problem here. If applicable, add screenshots to help explain.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:5
- Comments:12 (3 by maintainers)
There are still quite a few differences, and even after 2 years they still aren’t documented well. If I find more differences, I will document them here to start with, and then maybe I’ll put them in an article later, compadre. 😉
I can’t imagine why @PeterKottas had any issue with that. It works fine for me.
But in general, the legacy decorators in Babel behave different than legacy decorators in TypeScript. For example:
initializer
property instead of avalue
property, but in TypeScript there is never aninitializer
property, only avalue
property.useDefineForClassFields
is set tofalse
(otherwise many decorators would break).loose
option for theplugin-proposal-class-properties
option (which seems like a bug), which is opposite of TypeScript behavior.And there are more differences. Overall, they are two very different decorator systems, although they both supposedly are based on the legacy spec. Maybe one evolved with the legacy spec more than the other over time?
If anyone knows of more differences in detail, please do list them here. That would be helpful!