TypeScript:将实例传递给函数时,实现不起作用

TypeScript:将实例传递给函数时,实现不起作用,typescript,typeguards,Typescript,Typeguards,我有一个定义事件发射器的TypeScript接口 export interface Emitter<A extends {}> { on: <E extends keyof A>(event: E, listener: A[E]) => any; off: <E extends keyof A>(event: E, listener: A[E]) => any; } 这个 这很有效。现在我有了第二个类,它期望实现Emitter: 现在,当

我有一个定义事件发射器的
TypeScript
接口

export interface Emitter<A extends {}> {
  on: <E extends keyof A>(event: E, listener: A[E]) => any;
  off: <E extends keyof A>(event: E, listener: A[E]) => any;
}
这个

这很有效。现在我有了第二个类,它期望实现
Emitter

现在,当我尝试将
ObjectManager
的实例传递给
Watcher
类时,我得到一个类型错误:

const watcher = new Watcher(this.objectManager);
                            ^^^^^^^^^^^^^^^^^^
“ObjectManager”类型的参数不可分配给“Emitter”类型的参数。 属性“on”的类型不兼容。 Type'(事件:E,侦听器:Api[E])=>Promise'不可分配给Type'(事件:E,侦听器:any)=>any'。 参数“event”和“event”的类型不兼容。 类型“E”不可分配给类型“discover”|“service”。 类型“string”number“symbol”不可分配给类型“discover”|“service”。 类型“string”不可分配给类型“discover”|“service”。 类型“E”不可分配给类型“服务”。 类型“字符串”编号“符号”不可分配给类型“服务”。 类型“string”不可分配给类型“service”。ts(2345) 不过,我可以这样做:

const watcher = new Watcher(this.objectManager as Emitter<Api>);
const-watcher=new-watcher(this.objectManager作为发射器);
这很有效


现在我想知道怎么了。我是否使用了
实现
错误?

问题在于泛型
E
,它在
发射器
级别上是不同的,在
对象管理器
级别上引入了不同的东西。线索是从这两个泛型中删除一个。我的建议是把这个泛型放在
Emitter
接口的更高位置

interface Emitter<A extends {} = {}, E extends keyof A = keyof A> {
  on: (event: E, listener: A[E]) => any;
  off: (event: E, listener: A[E]) => any;
}
// or no generic for event version:
interface Emitter<A extends {} = {}> {
  on: (event: keyof A, listener: A[typeof event]) => any;
  off: (event: keyof A, listener: A[typeof event]) => any;
}

对不起,我的错误,ObjectManager当然是根据发射器的类型实现的。当然,使用任何一种方法都会奏效,但那会挫败目的,谢谢。我的Watcher实现一定是错误的,这段代码不适合我。我在TS操场上贴了一个例子。不幸的是,链接太长,所以我不得不在摘要中复制链接(omg)
class Watcher<E extends Emitter<any>> {
  constructor(emitter: E) {}
}
class ObjectManager implements Emitter<Api> {
  public async on<E extends keyof Api>(
    event: E,
    listener: Api[E]
  ): Promise<void> {
    // implementation omitted for the sake of this example
  }

  public async off<E extends keyof Api>(
    event: E,
    listener: Api[E]
  ): Promise<void> {
    // implementation omitted for the sake of this example
  }
}
const watcher = new Watcher(this.objectManager);
                            ^^^^^^^^^^^^^^^^^^
Argument of type 'ObjectManager' is not assignable to parameter of type 'Emitter<any>'.
  Types of property 'on' are incompatible.
    Type '<E extends "discover" | "service">(event: E, listener: Api[E]) => Promise<void>' is not assignable to type '<E extends string | number | symbol>(event: E, listener: any) => any'.
      Types of parameters 'event' and 'event' are incompatible.
        Type 'E' is not assignable to type '"discover" | "service"'.
          Type 'string | number | symbol' is not assignable to type '"discover" | "service"'.
            Type 'string' is not assignable to type '"discover" | "service"'.
              Type 'E' is not assignable to type '"service"'.
                Type 'string | number | symbol' is not assignable to type '"service"'.
                  Type 'string' is not assignable to type '"service"'.ts(2345)
const watcher = new Watcher(this.objectManager as Emitter<Api>);
interface Emitter<A extends {} = {}, E extends keyof A = keyof A> {
  on: (event: E, listener: A[E]) => any;
  off: (event: E, listener: A[E]) => any;
}
// or no generic for event version:
interface Emitter<A extends {} = {}> {
  on: (event: keyof A, listener: A[typeof event]) => any;
  off: (event: keyof A, listener: A[typeof event]) => any;
}
// below everything works.
class ObjectManager implements Emitter<Api> {
  public async on<E extends keyof Api>(
    event: E,
    listener: Api[E]
  ): Promise<void> {
    // implementation omitted for the sake of this example
  }

  public async off<E extends keyof Api>(
    event: E,
    listener: Api[E]
  ): Promise<void> {
    // implementation omitted for the sake of this example
  }
}
const e = new Watcher(new ObjectManager());