[TypeScript]Auto-Accessor Decorator

class Person {
  @accessor
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const person = new Person("John");
console.log(person.name); // John
person.name = "Jeff";
console.log(person.name); // Jeff

 
バリデーション付き Auto-Accessor

function MinLength(length: number) {
  return (target: any, context: ClassAccessorDecoratorContext) => {
    return {
      set(value: string) {
        if (value.length < length) {
          throw new Error(`Value must be at least ${length} characters long.`);
        }
        return value;
      }
    };
  };
}

class User {
  @accessor @MinLength(3)
  username: string;

  constructor(username: string) {
    this.username = username;
  }
}

const user = new User("John");
console.log(user.username); // John

user.username = "Bob"; // OK
// user.username = "Al"; // エラー: Value must be at least 3 characters long.

 
ログ出力付き Auto-Accessor

function LogAccessor(target: any, context: ClassAccessorDecoratorContext) {
  return {
    get(value: any) {
      console.log(`Getting value: ${value}`);
      return value;
    },
    set(value: any) {
      console.log(`Setting value to: ${value}`);
      return value;
    }
  };
}

class Product {
  @accessor @LogAccessor
  price: number;

  constructor(price: number) {
    this.price = price;
  }
}

const product = new Product(1000);
console.log(product.price); // Getting value: 1000, 1000

product.price = 1500; // Setting value to: 1500
console.log(product.price); // Getting value: 1500, 1500