为什么不能为“处理程序”功能变量具有多个签名?
以这种理想的方式,但以无效代码段为例:
<textarea id="sendie" maxlength = '100' ></textarea>
我真正想要的是这些东西:class MyEntityService {
private handleThing: (a: undefined) => undefined;
private handleThing: <T extends object>(a: T) => T;
private handleThing: <T extends object>(a: T | undefined) => object | T {
if (!a) return undefined;
// Various calls to other private methods here
return a;
}
}
是事件处理程序或promise的handleThing
主体,需要具有词法then
绑定(箭头函数是最简单的方法)以实现这一目标)。目的是this
维护多个签名,以便可以根据上下文(即,取决于使用它的位置)来选择最合适的签名。
我也尝试了以下操作,但是处理程序变量最终的类型为handleThing
,即所有输入均已有效删除:
any
仅拥有class MyEntityService {
private handleThing = this.handleThing_.bind(this);
private handleThing_(a: undefined): undefined;
private handleThing_<T extends object>(a: T): T;
private handleThing_<T extends object>(a: T | undefined): T | undefined {
if (!a) return undefined;
// Various calls to other private methods here
return a;
}
}
是不理想的:
一种选择是使用handleThing: <T extends object>(a: T | undefined) => object | undefined
函数并取消处理程序函数变量,但这将与我的团队为遇到这个难题的项目所建立的已建立的代码约定相违背。
因此,我问:
答案 0 :(得分:1)
要使第一个代码段起作用,您需要将handleThing
视为已初始化的属性而不是方法。这意味着您给它一个类型注释和一个值。请注意,重载函数的类型可以表示为每个签名的intersection(例如((x: string)=>number) & ((x: number)=>string)
),也可以表示为具有多个bare function signatures的单个对象类型(例如{{ 1}})。像这样:
{ (x: string): number; (x: number): string; }
更新到TypeScript 3.4或更高版本后,第二个代码段将按预期工作,因为TypeScript 3.4添加了对inferring generic types from uses of generic functions的更好支持。在TypeScript 3.3或更低版本中,返回的class MyEntityService {
private handleThing: {
(a: undefined): undefined;
<T extends object>(a: T): T;
} = <T extends object>(a: T | undefined) => {
if (!a) return undefined;
// Various calls to other private methods here
return a;
}
}
将去除所有泛型,并以bind()
取代,如您所见。
最后,我不确定为什么不选择一个签名:
any
因为如果您将class MyEntityService {
private handleThing = <T extends object | undefined>(a: T): T => {
if (!a) return undefined as T; // have to assert here
// Various calls to other private methods here
return a;
}
}
设置在(x: undefined) => undefined
和T
上,则object
应该与该签名匹配。
无论如何,希望能有所帮助;祝你好运!