Understanding TypeScript Decorators: Concepts, Types, and Practical Usage
This article explains what TypeScript decorators are, how they differ from Java annotations, classifies them by syntax and target, and provides clear code examples for plain decorators, decorator factories, and the five main decorator types used in front‑end development.
1. What Is a Decorator?
The official documentation defines a decorator as a special kind of declaration that can be attached to a class, method, accessor, property, or parameter. Decorators use the @ expression syntax; the expression must evaluate to a function that is invoked at runtime with the decorated declaration’s metadata as arguments.
This definition conveys several key points:
Decorators are applied to classes, properties, methods, or parameters.
They are written using @ followed by a function (or expression).
The decorator function is called at runtime, receiving information related to the target.
The function may return nothing or an object that can replace the decorated target.
Example code:
function MyDecorator(target: any) {
...
}
@MyDecorator
class User {
...
}For developers familiar with Java, this looks similar to Java annotations, but TypeScript decorators are invoked only at runtime, whereas Java annotations can affect source, compile‑time, and runtime phases.
2. Classification of Decorators
By syntax, decorators can be divided into:
Plain decorators (no parameters)
Decorator factories (can accept parameters)
By target, TypeScript defines five main decorator categories:
ClassDecorator
PropertyDecorator
MethodDecorator
ParameterDecorator
AccessorDecorator
The first four are most commonly used and will be introduced in detail below.
3. How to Write Decorators
The main difference between a plain decorator and a decorator factory is that the former cannot accept arguments, while the latter can.
3.1 Plain Decorator
A plain decorator is simply a function applied directly with the @ syntax.
/**
* Class decorator (plain syntax)
*/
export function Route(target: object) {
// TODO
...
}
//=========================================================
@Route()
struct DetailPage {
build() {
...
}
}3.2 Decorator Factory
A decorator factory returns a decorator function, allowing parameters to be passed when the decorator is used.
/**
* Class decorator (factory implementation)
*/
export function Route(routePath: string): ClassDecorator {
return (target: object) => {
// TODO
...
}
}
//=========================================================
@Route({ routePath: '/jump/entry/detail' })
struct DetailPage {
build() {
...
}
}3.3 Class Decorator (ClassDecorator)
A class decorator is declared immediately before a class declaration. It receives the class constructor as its sole argument and can monitor, modify, or replace the class definition.
Type definition:
type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;Example:
function CustomClassDecorator(info: string): ClassDecorator {
return (target: Function) => {
console.log(target); // [Function User]
console.log(info); // 你好
}
}
@CustomClassDecorator('你好')
class User {
public name!: string;
constructor() {
this.name = '马东锡';
}
}3.4 Property Decorator (PropertyDecorator)
A property decorator is declared immediately before a property declaration.
Type definition:
type PropertyDecorator = (target: Object, propertyName: string | symbol) => void;Example:
function CustomPropertyDecorator(userName: string): PropertyDecorator {
return (target: Object, propertyName: string | symbol) => {
console.log(target); // {}
console.log(propertyName); // userName
targetClassPrototype[propertyName] = userName;
}
}
class User {
@CustomPropertyDecorator('马东锡')
public userName!: string;
constructor() {}
}
let user = new User();
console.log(user.userName); // 马东锡3.5 Method Decorator (MethodDecorator)
A method decorator is declared immediately before a method declaration. It can monitor, modify, or replace the method definition.
Type definition:
type MethodDecorator = <T>(target: Object, methodName: string | symbol, propertyDescriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;Example:
function CustomMethodDecorator(info: string): MethodDecorator {
return (target: Object, methodName: any, propertyDescriptor: PropertyDescriptor) => {
console.log(target); // { sayHello: [Function (anonymous)] }
console.log(methodName); // sayHello
let originMethod = propertyDescriptor.value;
propertyDescriptor.value = function (...args: any) {
console.log('before');
console.log('我' + info + '来了'); // 我马东锡来了
originMethod.call(this, args);
console.log('after');
}
}
}
class User {
@CustomMethodDecorator('马东锡')
sayHello() {
console.log('执行sayHello()方法)');
}
}3.6 Parameter Decorator (ParameterDecorator)
A parameter decorator is declared immediately before a parameter declaration. It can inspect the target, method name, and the parameter’s index.
Type definition:
type ParameterDecorator = (target: Object, methodName: string | symbol, parameterIndex: number) => void;Example:
function CustomParameterDecorator(tag: string): ParameterDecorator {
return (target: any, methodName: string | symbol, parameterIndex: number) => {
console.log(tag); // 装饰实例方法的参数
console.log(target); // { sayHello: [Function (anonymous)] }
console.log(methodName.toString()); // sayHello
console.log(parameterIndex.toString()); // 0
}
}
class User {
constructor() {}
sayHello(@CustomParameterDecorator("装饰实例方法的参数") name: String) {
console.log("你好," + name);
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
