带有重载的Invokable接口

时间:2015-02-10 12:34:31

标签: interface typescript overloading

我想要将(外部)函数与之关联的多种类型。我决定将它们按照以下方式放入幕后阵列中:

var labelGenerators : ILabelGenerator[] = []

其中ILabelGenerator应该是类型可以具有的不同形状的通用接口,如:

interface ILabelGenerator{
  (container : SomeContainerObject, delta: IDeltaValues): string;
  (container : SomeContainerObject, x: number, y: number): string;
  (container : SomeContainerObject, x: Date, y: number): string;
}

现在,我不知道如何将项添加到labelGenerators数组,因为如果我执行类似的操作:

labelGenerators[0] = (container:SomeContainerObject, x:number, y: number) => {
   return "label 0"; //the real code uses the parameters
}

我收到类型(container:SomeContainerObject, x:number, y: number) => string is not assignable to type ILabelGenerator错误。

如何解决这个问题? (我使用TypeScript 1.3,但由于我有大约10个调用形状,1.4联合类型将非常笨重)

3 个答案:

答案 0 :(得分:2)

这应该可以避免编译器错误,因为你明确告诉TS:

labelGenerators[0] = <ILabelGenerator>(
     (container: SomeContainerObject, x: number, y: number) => { 
         return "label 0"; //the real code uses the parameters 
     });

答案 1 :(得分:1)

您的原始界面没有说“它可以是任何这些”,它说“它将与所有这些兼容” - 以满足您必须使用扩展类型或实现所有适当的重载。

您想要的界面是“它们将一个”。在这种情况下,您应该实际创建包含实际合同的接口。实现在合同中承诺的唯一事情是第一个参数是SomeContainerObject类型。就其他参数而言,所有赌注均已关闭。

合同允许调用代码知道它可以依赖什么。因此,我会使用以下界面:

interface ILabelGenerator{
  (container: SomeContainerObject, ...additional: any[]): string;
}

使用此界面的原因是您对ILabelGenerator的实施承诺。

例如,当您键入以下内容时...

labelGenerators[0](

你会真实地反映现实。

您的原始界面过度承诺,​​因为它表明“您可以调用您的首选签名”。这个版本说“我不知道你的第一个论点后你应该提供什么”。即这是事实!

答案 2 :(得分:0)

由于第二个参数需要与所有签名兼容。使用x:any