Although the TypeScript 5 has been officially realized with new decorators, the decorators documentation is still about decorators of TypeScript 4 (for the 1st April 2023).
The signature of decorator functions has been changed.
Experimentally I have 2 parameters with undefined
first one and metadata-like second one:
export default function VueReactiveDataField(
...blackBoxes: Array<unknown>
): void {
console.log(blackBoxes);
// ...
}
@VueComponentOptions
export default class ReactiveStateExperimentalSample {
@VueReactiveDataField
protected exampleReactiveField: string = "Experimental sample works fine";
}
The console output is:
What it their types and why first one is undefined?
Of course is has not "experimentalDecorators": true
.
{
"compilerOptions": {
"target": "ES2020",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": false, /* Actual for Vue3; see https://github.com/vuejs/vue-next/issues/4668 */
"allowJs": true, /* Actual for Vue3; */
"skipLibCheck": true,
"baseUrl": "./",
"paths": {
"@Source/*": [ "./Source/*" ]
},
"declaration": true
},
"include": [
"Project.d.ts",
"Source/**/*",
"Tests/**/*"
]
}
You can read about decorators in ECMAScript decorators proposal. Specifically for class field decorators the first argument is always undefined
. For the second argument TS5 provides ClassFieldDecoratorContext<This, Value>
helper type.
For example
function VueReactiveDataField(
_: undefined,
// `unknown` if you don't care about the type of the class where decorated
// property belongs
// `string` so that you can only decorate string properties
context: ClassFieldDecoratorContext<unknown, string>
): void {
console.log(_, context);
}
@VueComponentOptions
export default class ReactiveStateExperimentalSample {
@VueReactiveDataField
protected exampleReactiveField: string = "Experimental sample works fine";
}
Or make it generic
function VueReactiveDataField<
This,
// Will only work for properties of type `string`, `number` or `string | number` (or `never` but that's boring)
Value extends string | number
>(
_: undefined,
context: ClassFieldDecoratorContext<This, Value>
): void {
console.log(_, context);
}
@VueComponentOptions
export default class ReactiveStateExperimentalSample {
@VueReactiveDataField
protected exampleReactiveField: string = "Experimental sample works fine";
}