尽量保持简洁。问题出在 MyItemRepository.foo
- 请参阅内嵌注释。
class MyModel {}
class MyItem extends MyModel {
getFoo() {}
getBar() {}
}
interface IMyItemData {
foo: string;
bar: string;
}
class MyRepository<MyEntity extends MyModel, IMyEntityData extends any> {
protected getData(entities: MyEntity): IMyEntityData;
protected getData(entities: MyEntity[]): IMyEntityData[];
protected getData(entities: MyEntity | MyEntity[]): IMyEntityData | IMyEntityData[] {
if (Array.isArray(entities)) {
return this.getDataItems(entities);
}
return this.getDataItem(entities);
}
private getDataItem(entity: MyEntity): IMyEntityData {
return null;
}
private getDataItems(entities: MyEntity[]): IMyEntityData[] {
return [];
}
}
class MyItemRepository extends MyRepository<MyItem, IMyItemData> {
foo(surprise: MyItem | MyItem[]): IMyItemData[] {
let item: MyItem;
let items: MyItem[];
const itemData = this.getData(item); // correctly resolves type to IMyItemData
const itemsData = this.getData(items); // correctly resolves type to IMyItemData[]
// here I get the error that 'no overload matches this call'
const surpriseData = this.getData(surprise); // resolves type to IMyItemData & IMyItemData[]
return castArray(surpriseData); // Lodash method
}
}
const repo = new MyItemRepository();
const items = repo.foo(new MyItem()); // correctly resolves type to IMyItemData[]
还尝试检查 MyItemRepository.getData
中的实例,而不是检查是否传递了数组,但仍然存在同样的问题。
protected model: ModelConstructor<Entity>;
protected getData(entities: MyEntity | MyEntity[]): IMyEntityData | IMyEntityData[] {
if (entities instanceof this.model) {
return this.getDataItem(entities);
}
}
我不想使用类型保护是 MyItemRepository.foo
,因为我不关心 MyItemRepository.getData
的返回类型。没有它,有什么方法可以实现我想要的吗?
基本上我希望将 surpriseData
解析为 IMyItemData | IMyItemData[]
,而不是 IMyItemData & IMyItemData[]
。不知道它是从哪里来的。
目前使用一个有点hacky的解决方案:
const surpriseData = this.getData(castArray(surprise));
答案 0 :(得分:1)
重载函数的最后一行是实现签名,因此它不被视为重载之一。您在此处需要做的就是将最后一行输入两次——一次作为重载,一次作为实现。
protected getData(entities: MyEntity): IMyEntityData;
protected getData(entities: MyEntity[]): IMyEntityData[];
protected getData(entities: MyEntity | MyEntity[]): IMyEntityData | IMyEntityData[];
protected getData(entities: MyEntity | MyEntity[]): IMyEntityData | IMyEntityData[] {
这表示如果 entities
是任一输入类型,则数据是任一返回类型。重载是从上到下应用的,因此不必担心无意中扩大了更具体的类型。