A typescript
decorator that allows you to apply another decorator to all methods of a class.
npm i decorate-all
Note: since version
1.1.0
, this package uses thereflect-metadata
package as a peer dependency, so you need to have it installed.
A need for this decorator arose from having to decorate all methods (route handlers) of a NestJS controller class with the same parameter decorator. In the project, which is a multi-tenant application, most routes include a "tenantId" path parameter which needed to be specified using a route decorator. Repeating it over each method was tedious and error prone.
Thus, decorate-all
was born.
import { DecorateAll } from 'decorate-all';
const Uppercase = (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor,
) => {
const original = descriptor.value;
descriptor.value = function () {
return original.call(this).toUpperCase();
};
};
// instead of decorating each method on its own...
class Hello1 {
@Uppercase
world() {
return 'world';
}
@Uppercase
galaxy() {
return 'galaxy';
}
}
// ...use the DecorateAll decorator
@DecorateAll(Uppercase)
class Hello2 {
world() {
return 'world';
}
galaxy() {
return 'galaxy';
}
}
const hello1 = new Hello1();
console.log(hello1.world()); // logs "WORLD"
console.log(hello1.galaxy()); // logs "GALAXY"
const hello2 = new Hello2();
console.log(hello2.world()); // logs "WORLD"
console.log(hello2.galaxy()); // logs "GALAXY"
The second parameter of the DecorateAll
decorator takes an options object with the following options:
exclude: string[]
array of method names that won't be decorated
// apply the Uppercase decorator to all methods, except 'galaxy'
@DecorateAll(Uppercase, { exclude: ['galaxy'] })
class Hello {
world() {
return 'world';
}
galaxy() {
return 'galaxy';
}
universe() {
return 'universe';
}
}
const hello = new Hello();
console.log(hello.world()); // logs "WORLD"
console.log(hello.galaxy()); // logs "galaxy"
console.log(hello.universe()); // logs "UNIVERSE"
deep: boolean
By default, only the class' own methods are decorated. If you passdeep: true
, the decorator will be also applied to inherited methods of any extended class. (It can also be combined with the exclude option).
class Plain {
hi() {
return 'hi';
}
hello() {
return 'hello';
}
}
@DecorateAll(Uppercase, { deep: true })
class Decorated extends Plain {}
const plain = new Plain();
console.log(plain.hi()); // logs "hi"
console.log(plain.hello()); // logs "hello"
const decorated = new Decorated();
console.log(decorated.hi()); // logs "HI"
console.log(decorated.hello()); // logs "HELLO"