Adding initialization to the constructor
Suppose you want to add some additional logic to the constructor of a class.
type AnyClass = { new(...args: any[]): any }/**/**
* Simple User class with scopes/**
* Simple User class with scopes
*/class User { id: string scope: Set<string> constructor(id: string, scopes: string[]) { this.id = id this.scope = new Set(scopes) }}/**/**
* A decorator which limits other class definitions to use the scope/**
* A decorator which limits other class definitions to use the scope
*/function limitScope(...scopes: string[]) { return function<T extends AnyClass>(target: T): T { // Create a synthetic superclass return class extends target { constructor(...args: any[]) { super(...args) // Search constructor arguments for a User object const user = args.find((arg) => (arg instanceof User)) if (user) { // Check scopes and throw error if (! scopes.every((scope) => user.scope.has(scope))) { throw new Error('User does not have scope') } } else if (scopes.length > 0) throw new Error('No User provided to validate scopes') } } as T }}@limitScope('admin')class Refund { constructor(createdBy: User) { console.log('Creating a refund') } }const admin = new User('admin_user_id', ['admin'])const customer = new User('customer_id', ['user'])const refund = new Refund(admin)