【问题标题】:Getting a typescript class recognized as an interface获取识别为接口的打字稿类
【发布时间】:2019-11-15 06:34:50
【问题描述】:

在尝试升级到 TypeScript 3.5 时,我遇到了一个签名问题,该签名由于某种奇怪的原因被 ts 编译器忽略了,但已经存在多年了。

第三方框架 (knockoutJS) 要求我传入符合此要求的内容:

interface ViewModelFunction {
    (params?: any): any;
}

显然在运行时它可以做这样的事情:

class MyClass {
  public foobar: string;
  constructor(params: { foo: string; bar: number }) {
    this.foobar = params.foo + params.bar;
  }
  public doSomething = () => {
    return this.foobar.length;
  }
}

然后将 MyClass 发送到需要 ViewModelFunction 作为属性的函数中。由于代码有效,这主要是打字稿问题。虽然这是一个谜(但原因并不重要)ts3.5 突然注意到这一点,但没有任何版本的 typescript 会接受类似

class MyClass implements ViewModelFunction{...}

那么有什么方法可以将 Class 转换为 ViewModelFunction-interface 吗?

【问题讨论】:

  • 你确定不是淘汰赛定义发生了变化吗?从至少 2.4 开始,这是一个错误:typescript-play.js.org/?ts=2.4.1#code/…
  • 是的。我认为这是 TS3.5 中联合改进的结果。如需更准确的示例,请参阅:typescript-play.js.org/?ts=3.3.3#code/…
  • 你能不能给我一个minimal reproducible example 让我看看你在说什么?我很困惑MyClass 如图所示将如何实现ViewModelFunction,所以也许我遗漏了一些东西。您可以使用declaration merging 来消除警告,就像interface MyClass extends ViewModelFunction {} 一样,但我不敢建议这样做,因为它看起来很危险。
  • 是的,在我上面的评论中是链接,您可以从顶部的下拉列表中选择 ts-version,它从 3.5 开始失败。
  • 代码应该在问题中而不是评论中(您可以编辑问题)。无论如何,看起来您正在将类 constructor 传递给只接受 ViewModelFunction... 的东西,但这确实应该是一个错误。如果我尝试像函数一样调用构造函数,则可能会在运行时收到TypeError: class constructors must be invoked with |new| 之类的错误。理想情况下,您应该创建一个实际的ViewModelFunction 实例,例如(x:any)=>new MyClass(x),并使用它而不是MyClass。这有帮助吗?或者如果没有,你能说明它应该如何工作吗?祝你好运!

标签: typescript knockout.js typescript-typings


【解决方案1】:
const viewModel: ViewModelFunction = params => new MyClass(params);

【讨论】:

    【解决方案2】:

    您可以将doSomething 和公共foobar 移动到一个接口,并拥有一个创建实现该接口和ViewModelFunction 的对象的函数。

    interface ViewModelFunction {
      (params?: any): any;
    }
    
    interface MyClass {
      foobar: string;
      doSomething(): number;
    }
    
    interface MyF extends MyClass, ViewModelFunction {}
    
    function getMyF(foobar: string): MyF {
      const res = () => {yourViewModel();};
      res.foobar = foobar;
      res.doSomething = () => foobar.length;
      return res;
    }
    

    【讨论】:

    • 我需要将与 ViewModelFunction 匹配的内容发送到另一个函数中。我认为这种解决方法不会以任何方式改变这种情况。
    • getMyF 的结果与ViewModelFunction 匹配。
    • 这不是一种解决方法,它实际上是创建一个也有方法的函数的有效解决方案。
    • const getViewModel = (): ViewModelFunction => (params) => new MyClass(params); 这个简单的解决方案似乎可以解决问题。无需重新实现功能。
    猜你喜欢
    • 1970-01-01
    • 2023-01-11
    • 2019-06-01
    • 2017-02-19
    • 2017-09-16
    • 2020-06-12
    • 2022-11-25
    • 1970-01-01
    • 2017-09-02
    相关资源
    最近更新 更多