Код IT Загрузка примера кода…

TypeScript main.ts
type Events = {
  CART_ITEM_ADDED: { productId: string; price: number };
  USER_AUTHENTICATED: { userId: string; role: "admin" | "customer" };
  PAYMENT_COMPLETED: { orderId: string; currency: "USD" | "EUR" };
};

class TypedEmitter {
  private handlers: {
    [K in keyof Events]?: Array<(payload: Events[K]) => void>;
  } = {};

  on<K extends keyof Events>(event: K, fn: (payload: Events[K]) => void): void {
    const list = this.handlers[event] ?? [];
    list.push(fn);
    this.handlers[event] = list;
  }

  emit<K extends keyof Events>(event: K, payload: Events[K]): void {
    for (const fn of this.handlers[event] ?? []) {
      fn(payload);
    }
  }
}

const bus = new TypedEmitter();

bus.emit("CART_ITEM_ADDED", { productId: "p_001", price: 49.99 });

// bus.emit("PAYMENT_COMPLETED", {
//   orderId: "o_456",
//   currency: "GBP",
// });
// ошибка: "GBP" не входит в "USD" | "EUR"

bus.on("PAYMENT_COMPLETED", ({ orderId, currency }) => {
  console.log(orderId, currency);
});

// bus.on("PAYMENT_COMPLETED", ({ userId }) => {
//   console.log(userId);
// });
// ошибка: userId есть у USER_AUTHENTICATED, не у PAYMENT_COMPLETED
type Events = {
  CART_ITEM_ADDED: { productId: string; price: number };
  USER_AUTHENTICATED: { userId: string; role: "admin" | "customer" };
  PAYMENT_COMPLETED: { orderId: string; currency: "USD" | "EUR" };
};

class TypedEmitter {
  private handlers: {
    [K in keyof Events]?: Array<(payload: Events[K]) => void>;
  } = {};

  on<K extends keyof Events>(event: K, fn: (payload: Events[K]) => void): void {
    const list = this.handlers[event] ?? [];
    list.push(fn);
    this.handlers[event] = list;
  }

  emit<K extends keyof Events>(event: K, payload: Events[K]): void {
    for (const fn of this.handlers[event] ?? []) {
      fn(payload);
    }
  }
}

const bus = new TypedEmitter();

bus.emit("CART_ITEM_ADDED", { productId: "p_001", price: 49.99 });

// bus.emit("PAYMENT_COMPLETED", {
//   orderId: "o_456",
//   currency: "GBP",
// });
// ошибка: "GBP" не входит в "USD" | "EUR"

bus.on("PAYMENT_COMPLETED", ({ orderId, currency }) => {
  console.log(orderId, currency);
});

// bus.on("PAYMENT_COMPLETED", ({ userId }) => {
//   console.log(userId);
// });
// ошибка: userId есть у USER_AUTHENTICATED, не у PAYMENT_COMPLETED