Перейти к содержимому

Decorators (Stage 3 / TS 5.0)

TC39 Stage 3 — это новые декораторы, не experimentalDecorators. На интервью спрашивают разницу: новые принимают (value, context), не имеют доступа к prototype, не передают PropertyDescriptor. Красный флаг — писать на старом синтаксисе и не знать про ClassMethodDecoratorContext.

Старые vs новые — сигнатуры и tsconfig:

// experimentalDecorators (legacy):
// function log(target, key, descriptor) { ... }
// Stage 3 (TS 5.0+, без experimentalDecorators):
function logged<This, Args extends any[], Return>(
target: (this: This, ...args: Args) => Return,
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
const name = String(context.name);
return function (this: This, ...args: Args): Return {
console.log(`-> ${name}`, args);
const r = target.apply(this, args);
console.log(`<- ${name}`, r);
return r;
};
}
class Api {
@logged
get(id: string) { return { id }; }
}

Field/getter/accessor декораторы — у каждого свой context:

function nonEnumerable<T, V>(
_value: undefined,
context: ClassFieldDecoratorContext<T, V>
) {
context.addInitializer(function () {
Object.defineProperty(this, context.name, { enumerable: false });
});
}
class User {
@nonEnumerable
internalId = crypto.randomUUID();
}

Декоратор класса — заменяет конструктор:

function sealed<T extends new (...a: any[]) => any>(
value: T,
_context: ClassDecoratorContext<T>
) {
Object.seal(value);
Object.seal(value.prototype);
return value;
}
@sealed
class Service { name = 'svc' }

Итог: Новые декораторы — это (value, context), без PropertyDescriptor; включаются без experimentalDecorators в TS 5.x.