【问题标题】:Define a callable TypeScript function with extended prototype使用扩展原型定义一个可调用的 TypeScript 函数
【发布时间】:2017-04-25 14:23:23
【问题描述】:

我想定义一个可调用函数foo()(不是类!我不想在这里使用new 运算符),它还有一个属性foo.bar()。在普通的 JS 中,它看起来像这样:

function foo() {
    // ...
}

foo.prototype.bar = function bar() {
    // ...
}

我在 TypeScript 中使用类似这样的界面进行了尝试:

interface IFoo {
    (): any;
    bar(): any;
}

const foo: IFoo = function(): any {
    // ...
};

foo.prototype.bar = function bar(): any {
    // ...
};

但我得到一个错误:

error TS2322: Type '() => any' is not assignable to type 'IFoo'.

似乎 TS 抱怨定义 foo 和它的属性 bar 之间的中间状态,因为 foo 还没有属性 bar 它不能分配给 const 类型的 @ 987654333@。 我该如何解决这个问题?

换个方式问:我怎样才能为IFoo提供一个实现?

【问题讨论】:

  • 有使用接口的理由吗?如果您以后需要该接口,您可以随时使用typeof foo
  • @SebastianSebald 我不在乎它应该是一个接口或任何其他类型定义。但我确实需要该类型的名称,以便我可以拥有该类型的变量。我的示例中的接口准确地描述了我想要做什么,我只是不知道如何为其提供实现

标签: javascript typescript interface


【解决方案1】:

如果您只想将foo 作为类型注释,您可以这样做:

const foo = function() {};
foo.prototype.bar = function bar() {};

type IFoo = typeof foo;

【讨论】:

  • 编译器似乎无法识别并强制将prototype.bar 作为类型的一部分。例如这编译没有错误:const foo2: IFoo = function() {}; 尽管该函数的原型上没有bar
  • 当我尝试这个const foo3: IFoo = 1; 时,我得到一个错误:error TS2322: Type 'number' is not assignable to type '() => void' 这证明编译器不认为bar 是类型的一部分。
  • 好吧,无论如何您都不能为IFoo 分配号码。编译器可能只是不会在错误消息中显示整个原型。您可以查看我的example on the playgroundbar 已正确添加到 foo
  • 顺便说一句,如果您为prototype 设置了某些内容,则在创建实例时将可用。例如。 foo.barundefinedconst myFoo = new foo() + myFoo.bar 有效。
  • 好的,但是我的第一个例子const foo2: IFoo = function() {}; 也会导致编译错误,因为foo2 的原型上没有bar。但它编译没有错误。 see here
【解决方案2】:

我找到了一个使用显式转换的解决方案

interface IFoo {
    (): any;
    bar(): any;
}

// explicit cast
const foo: IFoo = <IFoo>function(): any {
    // ...
};

foo.prototype.bar = function bar(): any {
    // ...
};

我不确定这是不是最好的方法......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多