Хотя TypeScript 5 был официально реализован с новыми декораторами, документация декораторов по-прежнему посвящена декораторам TypeScript 4 (на 1 апреля 2023 года).
Сигнатура функций декоратора изменена.
Экспериментально у меня есть 2 параметра с undefined
первым и вторым, похожим на метаданные:
export default function VueReactiveDataField(
...blackBoxes: Array<unknown>
): void {
console.info(blackBoxes);
// ...
}
@VueComponentOptions
export default class ReactiveStateExperimentalSample {
@VueReactiveDataField
protected exampleReactiveField: string = "Experimental sample works fine";
}
Вывод консоли:
Каковы их типы и почему первый не определен?
Конечно нет "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/**/*"
]
}
Вы можете прочитать о декораторах в Предложении декораторов ECMAScript. В частности, для декораторов полей класса первым аргументом всегда является undefined
. Для второго аргумента TS5 предоставляет вспомогательный тип ClassFieldDecoratorContext<This, Value>
.
Например
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.info(_, context);
}
@VueComponentOptions
export default class ReactiveStateExperimentalSample {
@VueReactiveDataField
protected exampleReactiveField: string = "Experimental sample works fine";
}
Или сделать его универсальным
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.info(_, context);
}
@VueComponentOptions
export default class ReactiveStateExperimentalSample {
@VueReactiveDataField
protected exampleReactiveField: string = "Experimental sample works fine";
}