Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

类型安全的EventEmitter #49

Open
jiangshanmeta opened this issue Mar 30, 2022 · 0 comments
Open

类型安全的EventEmitter #49

jiangshanmeta opened this issue Mar 30, 2022 · 0 comments

Comments

@jiangshanmeta
Copy link
Owner

type MakeArray<T> = T extends any[] ? T : [T];

type EventMap<T> = {
  // 支持函数自定义个参数
  [K in keyof T]?: ((...args: MakeArray<T[K]>) => void)[];
};

export default class EventEmitter<T> {
  private _events: EventMap<T> = {};

  public on<E extends keyof T>(type: E, fn: (...rest: MakeArray<T[E]>) => void) {
    if (!this._events[type]) {
      this._events[type] = [];
    }
    this._events[type]?.push(fn);
  }

  public emit<E extends keyof T>(type: E, ...args: MakeArray<T[E]>) {
    const fns = this._events[type];
    fns?.forEach((fn) => {
      fn(...args);
    });
  }

  public off<E extends keyof T>(type: E, fn: (...args: MakeArray<T[E]>) => void) {
    this._events[type] = this._events[type]?.filter((item) => item !== fn);
  }
}

const event = new EventEmitter<{
  empty: [];
  one: string;
  multi: [number, string];
}>();

// 不需要额外参数,多传参会报错
event.emit('empty')
// 只能传一个 string类型的参数 注意上面 泛型参数也可以写为 one: [string]
event.emit('one','a')
// 需要两个参数
event.emit('multi',1,'')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant