I have a decorator in TypeScript:
const bindMethod = (method: any): PropertyDecorator =>
((target: any, name?: PropertyKey): any => {
if(name === undefined) {
throw new Error('Bound decorator must be used with a property name.');
}
return {
get(): any {
return target[method].bind(this);
}
};
});
class MyClass {
@bindMethod('example')
myMethod!: any;
example(): string {
return 'example';
}
}
I am trying to convert this decorator to TypeScript 5. Here is my revised version:
const bindMethod = (<
This,
Value
>(method: keyof This): any => ((
_value: undefined,
context: ClassFieldDecoratorContext<This, Value>
) => {
if(context.private) {
throw new Error('Bound decorator cannot be used on private properties.');
}
context.addInitializer(function(this: This) {
(this as any)[method] = (this[method] as CallableFunction).bind(this);
});
}));
Here is the JavaScript output for the decorator:
const example = (i) => (n, r) => {
if (r.private)
throw new Error("Bound decorator cannot be used on private properties.");
r.addInitializer(function() {
this[i] = this[i].bind(this);
});
};
export {
example as bind
};
However, I am encountering a runtime error:
TypeError: context.addInitializer is not a function
.
What could be the issue here?
Here is the configuration I am using:
{
"compilerOptions": {
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"alwaysStrict": true,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"useUnknownInCatchVariables": true,
"module": "es6",
"moduleResolution": "node10",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es2017",
"dom"
],
"target": "es2017",
"skipLibCheck": true,
"composite": true,
"rootDir": "./src",
"outDir": "./dist"
},
"files": [
"./src/bound.ts",
"./src/index.ts"
],
"include": [
"./src/**/*.ts"
],
"exclude": [
"./node_modules",
"./dist"
]
}