在父类中,我定义了一个具有不同参数的方法:存储中的索引或元素,并且根据参数,我通过索引从存储中获取元素或仅使用给定的元素。
因此,我使用重载来定义这些方法:
class Parent<T> {
items: T[] = [];
item: T = {} as T;
applyMethod(index: number): void;
applyMethod(item: T): void;
applyMethod(param: number | T): void {
if (typeof param === 'number') {
param = this.items[param];
}
this.item = param;
}
}
class Child1<T> extends Parent<T> {
// In my application, I actually add an id: string overload.
override applyMethod(param: number | T): void {
// Do something more before calling:
super.applyMethod(param);
}
}
class Child2<T> extends Parent<T> {
override applyMethod(param: number | T): void {
if (typeof param === 'number') {
super.applyMethod(param);
} else {
super.applyMethod(param);
}
}
}
也可以在TS Playground看到它。
在 Child1 中,我有一个错误:
No overload matches this call.\
Overload 1 of 2, '(index: number): void', gave the following error.\
Argument of type 'number | T' is not assignable to parameter of type 'number'.\
Type 'T' is not assignable to type 'number'.
Overload 2 of 2, '(item: T): void', gave the following error.\
Argument of type 'number | T' is not assignable to parameter of type 'T'.\
'T' could be instantiated with an arbitrary type which could be unrelated to 'number | T'.(2769
我可以像 Child2 中所示解决它,但这很奇怪/愚蠢。
另一种解决方法是定义
applyMethod(param: any): void {}
而不是 number | T
。这是经典的,这就是我最初所做的,但我发现 TS 只能看到 param: any
参数定义,因此我输了。
我选择了另一种方式,打电话给
super.applyMethod(param as any);
。至少,输入会保留其打字内容。
还有其他更优雅的方式吗?我错过了什么吗?
正如 jcalz 所建议的,使用重载可能会出现问题。
他们的优点之一是允许根据过载来个性化 JSDoc 注释:
/**
* Set the active item to the item at the specified index .
*
* @param index - The index of the item to be set as active.
*/
setActiveItem(index: number): void;
/**
* Set the active item to the specified item.
*
* @param item - The item to be set as active.
*/
setActiveItem(item: I): void;
setActiveItem(param: number | I): void {
}
一旦删除重载,我必须制作更通用的文档:
/**
* Set the active item to the given item or the one at the specified index.
*
* @param param - The item itself or the index of the item to be set as active.
*/
setActiveItem(param: number | I): void {
}
它至少简化了代码,并且最终更具可读性,所以还可以。