如何告诉打字稿关于另一个模块的函数"mixed in"?

How to tell typescript about functions "mixed in" from another module?

我遇到这种情况:

// Application.ts
import MicroEvent from 'microevent-github'

class Application {
  // stuff...
  something() {
    // It is also saying "trigger" is undefined,
    // but it IS defined, MicroEvent defined it.
    this.trigger('foo')
  }
}

// get the `bind`, `unbind`, and other methods from MicroEvent
MicroEvent.mixin(Application)

const app = new Application()

const handleFoo = () => console.log('foo')

// try to use them, get the squiggly errors saying
// `bind` doesn't exist on Application, etc.
application.bind('foo', handleFoo)
application.unbind('foo', handleFoo)

我已将 MicroEvent“混合”到我的应用程序中,这会向对象添加一些方法。但是,VSCode 抱怨 bindunbind 在 Application 实例中不存在......但是它确实存在,我如何告诉打字稿接受这个?

添加这个不起作用:

type Application = {
  bind: (eventType: string, callback: () => void) => void
  unbind: (eventType: string, callback: () => void) => void
  trigger: (eventType: string) => void
}

Typescript 不知道 mixin 正在修改 class。

您可以用 declare 语句填充它,这些语句告诉打字稿某些类型存在,但不提供任何实现。这有点危险,因为您正在创建一个没有类型检查以确保其安全实现的接口,但是当使用非类型化库时,您可能别无选择。

class Application {
    declare bind: (eventType: string, callback: () => void) => void
    declare unbind: (eventType: string, callback: () => void) => void
    declare trigger: (eventType: string) => void

    //...
}

Playground


要重用它,您可以创建一个抽象基础 class 来声明这些方法,并从中继承。

abstract class MicroEventBase {
  declare bind: (eventType: string, callback: () => void) => void
  declare unbind: (eventType: string, callback: () => void) => void
  declare trigger: (eventType: string) => void
}

class Application extends MicroEventBase {
  //...
}

Playground