我试图重载一个函数,所以当在其他地方使用该函数时,它会正确显示一个项目数组,无效或单个项目的结果:
getSelected(type): void;
getSelected(type): IDataItem;
getSelected(type): IDataItem[];
getSelected(type:string, one:boolean = true):any {
if (!type) {
return;
}
if (one) {
return _.reduce<IDataItem, IDataItem>(sections[type], (current: IDataItem, p: IDataItem) => {
return p.selected === true ? p : current;
}, void 0);
}
return _.filter<IDataItem>(sections[type], (p: IDataItem):boolean => {
return p.selected === true && p.enabled === true;
});
}
它给了我错误&#34;错误TS2175:超载只能通过返回类型而有所不同。&#34; 。我怎样才能发出返回类型的许多可能性呢?
答案 0 :(得分:4)
值得注意的是有关原始代码的几点......
这些是“过载签名” - 您可以调用它们。
getSelected(type): void;
getSelected(type): IDataItem;
getSelected(type): IDataItem[];
下一行是“实施签名” - 您不能直接调用它。
getSelected(type:string, one:boolean = true):any {
这意味着,就目前而言,您无法传递one
参数。
type
参数。您的重载未指定type
参数的类型,这些类型将具有any
类型 - 但我认为您可能希望将此限制为字符串。每个签名都需要注释......
type: string
如果您在true
参数中传递one
,则表明的签名,您将获得一个结果。如果你传递假,你会得到多个。您不能在布尔类型上使用专门的重载签名,只能使用字符串 - 因此您无法确定返回值是单个项还是集合。
此外,如果您可以传递字符串并获得void
返回类型,或者传递字符串并获得IDataItem
返回类型...编译器无法预测您将获得哪些。 ..所以你不能使用这个签名。
鉴于所有这些约束,唯一有效的重载将是:
class Example {
getSelected(type: string): any;
getSelected(type: string, one: boolean): any;
getSelected(type: string, one: boolean = true) : any {
}
}
这与更简单的完全相同:
class Example {
getSelected(type: string, one: boolean = true) : any {
}
}
很抱歉花了这么长时间才得到答案......
class Example {
getSelectedItem(type: string) : IDataItem {
// return just one
}
getAllSelectedItems(type: string): IDataItem[] {
// return all matches as a collection
}
}
有两种方法。一个用于获得单个项目,一个用于获取集合。将“空类型”案例处理为错误或返回适当的空对象以表示无结果(即不需要void
返回类型)。
答案 1 :(得分:2)
使用泛型以帮助编译器确定正确的值:
getSelected<T>(type:string, one:boolean = true): T {
// ...
}
getSelected<void>('abc');
var aDataItem = getSelected<IDataItem>('abc');
var aList = getSelected<IDataItem[]>('abc');
答案 2 :(得分:2)
如果您可能根据传入的数据的内容返回任何内容,并且这些可能的返回值之间没有通用类型,则应将返回类型声明为any
并强制执行调用代码使用类型断言。
我不喜欢Tarh的建议,因为它暗示了没有的类型安全。
从单个函数调用中返回不同类型的数据是代码气味;它给调用者带来了很多责任,以了解输入和输出之间的关系。您最好使用getSelectedSingle
,getSelectedMultiple
和getSelectedNone
。