具有重载的可调用接口
Invokable interfaces with overloads
我有多种类型要与(外部)函数相关联。我决定将它们保存在幕后数组中,如下所示:
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 联合类型将非常笨重)
因为第二个参数需要与所有签名兼容。使用 x:any
这应该可以避免编译器错误,因为您明确告诉 TS:
labelGenerators[0] = <ILabelGenerator>(
(container: SomeContainerObject, x: number, y: number) => {
return "label 0"; //the real code uses the parameters
});
您的原始接口没有说 "it can be any of these",它说 "it will be compatible with all of these" - 以满足您必须使用扩展类型或实现所有适当的重载。
您想要的界面是"it will be one of these"。在这种情况下,您实际上应该创建包含实际合同的接口。实现在契约中唯一承诺的是第一个参数的类型为 SomeContainerObject
。就附加参数而言,一切皆有可能。
合同的存在是为了让调用代码知道它可以依赖什么。因此,我会使用以下接口:
interface ILabelGenerator{
(container: SomeContainerObject, ...additional: any[]): string;
}
使用此接口的原因是,这就是您对 ILabelGenerator
.
实现的全部承诺
例如,当您键入以下内容时...
labelGenerators[0](
你会真实地反映现实。
您的原始界面承诺过度,因为它建议 "you can call your preferred signature"。这个版本说 "I have no idea what you should supply after your first argument"。也就是说,这是事实!
我有多种类型要与(外部)函数相关联。我决定将它们保存在幕后数组中,如下所示:
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 联合类型将非常笨重)
因为第二个参数需要与所有签名兼容。使用 x:any
这应该可以避免编译器错误,因为您明确告诉 TS:
labelGenerators[0] = <ILabelGenerator>(
(container: SomeContainerObject, x: number, y: number) => {
return "label 0"; //the real code uses the parameters
});
您的原始接口没有说 "it can be any of these",它说 "it will be compatible with all of these" - 以满足您必须使用扩展类型或实现所有适当的重载。
您想要的界面是"it will be one of these"。在这种情况下,您实际上应该创建包含实际合同的接口。实现在契约中唯一承诺的是第一个参数的类型为 SomeContainerObject
。就附加参数而言,一切皆有可能。
合同的存在是为了让调用代码知道它可以依赖什么。因此,我会使用以下接口:
interface ILabelGenerator{
(container: SomeContainerObject, ...additional: any[]): string;
}
使用此接口的原因是,这就是您对 ILabelGenerator
.
例如,当您键入以下内容时...
labelGenerators[0](
你会真实地反映现实。
您的原始界面承诺过度,因为它建议 "you can call your preferred signature"。这个版本说 "I have no idea what you should supply after your first argument"。也就是说,这是事实!