重载只能通过返回类型来区分

时间:2014-07-29 18:20:52

标签: typescript overloading

我试图重载一个函数,所以当在其他地方使用该函数时,它会正确显示一个项目数组,无效或单个项目的结果:

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; 。我怎样才能发出返回类型的许多可能性呢?

3 个答案:

答案 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');

See also the documentation

答案 2 :(得分:2)

如果您可能根据传入的数据的内容返回任何内容,并且这些可能的返回值之间没有通用类型,则应将返回类型声明为any并强制执行调用代码使用类型断言。

我不喜欢Tarh的建议,因为它暗示了没有的类型安全。

从单个函数调用中返回不同类型的数据是代码气味;它给调用者带来了很多责任,以了解输入和输出之间的关系。您最好使用getSelectedSinglegetSelectedMultiplegetSelectedNone