HarmonyOS 5 Decorator Principles and Custom Decorator Guide
In HarmonyOS development with ArkTS, decorators provide a powerful and concise way to implement component logic, manage state, and customize behavior. This guide explains what decorators are, how they work internally, and how to create custom decorators within the constraints of the ArkTS language.
I. What Is a Decorator in HarmonyOS?
In ArkTS (an extension of TypeScript), a decorator is a special kind of declaration that can annotate and modify classes, methods, and properties. It is commonly used for metaprogramming — enhancing functionality without altering the original code logic.
Common Built-in HarmonyOS Decorators
-
Component decorators:
@Component
,@Entry
,@Builder
,@CustomDialog
, etc. -
State decorators:
@State
,@Prop
,@Link
,@Observed
,@ObservedV2
, etc.
Example:
@Component
struct MyComponent {
@State count: number = 0;
}
II. Internal Principles of Decorators in ArkTS
ArkTS compiles decorators into function calls that wrap the target object. These function calls can modify or enhance the behavior of the class, method, or property being decorated.
1. Class Decorators
Applied above a class declaration. They receive the constructor as a parameter.
function logDecorator(constructor: Function) {
console.log(`Class ${constructor.name} is created.`);
}
@logDecorator
class MyComponent {
constructor() {
console.log('MyComponent instance is created.');
}
}
2. Method Decorators
Used to wrap or alter the behavior of class methods. Useful for logging, throttling, or debouncing:
export function debounce(timeout: number) {
return function (target: Object, propKey: string, descriptor: PropertyDescriptor) {
let timer: number = 0;
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
timer && clearTimeout(timer);
timer = setTimeout(() => original.apply(this, args), timeout);
};
};
}
export function throttle(wait: number) {
return function (target: Object, propKey: string, descriptor: PropertyDescriptor) {
let last = 0;
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
const now = Date.now();
if (now - last >= wait) {
original.apply(this, args);
last = now;
}
};
};
}
🛑 Note: ArkTS does not support any
or unknown
. Use Object
as a workaround.
3. Property Decorators
Applied to class properties. Can be used to add validation or reactive logic.
function positiveNumber(target: Object, propertyKey: string) {
let value: number;
Object.defineProperty(target, propertyKey, {
get: () => value,
set: (newValue: number) => {
if (newValue < 0) {
throw new Error(`${propertyKey} must be a positive number.`);
}
value = newValue;
},
enumerable: true,
configurable: true
});
}
class MyModel {
@positiveNumber
age: number = 20;
}
const model = new MyModel();
model.age = -1; // Throws error
III. How to Define Custom Decorators in ArkTS (HarmonyOS)
Because ArkTS enforces strong typing and disallows any
, custom decorators must follow stricter conventions.
Method Decorator Example
function methodLogger(target: Object, key: string, descriptor: PropertyDescriptor) {
const originalMethod: Function = descriptor.value;
descriptor.value = (...args: Object[]) => {
console.log(`Calling ${key} with args: ${args}`);
const result = originalMethod(...args);
console.log(`Returned from ${key}: ${result}`);
return result;
};
return descriptor;
}
IV. Practical Example: Custom Method Decorator in a Component
@Entry
@Component
struct DecoratorDemoComponent {
@State message: string = 'Hello HarmonyOS';
@methodLogger
private processData(input: string): string {
console.log('Processing data...');
return `Processed Data: ${input.toUpperCase()}`;
}
aboutToAppear() {
const result = this.processData('decorator demo');
console.log('Final Result:', result);
this.message = result;
}
build() {
Column({ space: 30 }) {
Text(this.message)
.fontSize(24)
.margin(10);
Button('Click to Trigger Method')
.onClick(() => this.processData('button click'))
.margin(10);
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center);
}
}
V. Summary & Recommendations
- ArkTS decorators are essential in HarmonyOS development for enhancing components, managing state, and abstracting logic.
- Avoid
any
and useObject
for maximum compatibility. - Method decorators like
@debounce
and@throttle
improve performance and control. - When creating custom decorators, always respect ArkTS' strict typing system.
Recommended Practices:
Decorator Type | Use Case | Notes | |||
---|---|---|---|---|---|
@State |
Local reactive state | Re-renders on update | |||
@Prop |
Receive immutable data | One-way data flow |
Top comments (0)