Generics 如何在TypeScript中使用泛型在重载函数中进行类型转换

Generics 如何在TypeScript中使用泛型在重载函数中进行类型转换,generics,casting,typescript,overloading,Generics,Casting,Typescript,Overloading,在我正在处理的库中,我有一个方法可以确保某些内容属于IList类型,如果不是,它应该将其转换为IList类型的实例。请参阅下面的代码: 1 import { IList, isList } from './list'; 2 3 import Unit from './unit'; 4 import ArrayList from './array_list'; 5 6 export default function factory<V,I>(obj:

在我正在处理的库中,我有一个方法可以确保某些内容属于
IList
类型,如果不是,它应该将其转换为
IList
类型的实例。请参阅下面的代码:

1    import { IList, isList } from './list';
2
3    import Unit      from './unit';
4    import ArrayList from './array_list';
5
6    export default function factory<V,I>(obj: IList<V,I>): IList<V,I>;
7    export default function factory<V>(obj: V[]): IList<V,number>;
8    export default function factory<V>(obj: V): IList<V,number> {
9      if(isList(obj)) return obj;
10     if(Array.isArray(obj)) return new ArrayList(obj);
11     return new Unit(obj);
12   }
1从“/list”导入{IList,isList};
2.
3从“./单位”导入单位;
4从“/array_list”导入ArrayList;
5.
6导出默认功能工厂(obj:ILST):ILST;
7导出默认函数工厂(obj:V[]):IList;
8导出默认功能工厂(obj:V):IList{
9如果(isList(obj))返回obj;
10如果(Array.isArray(obj))返回新的ArrayList(obj);
11返回新装置(obj);
12   }
此方法无法编译,请参见以下错误:

src/factory.ts(9,30): 2322 Type 'V' is not assignable to type 'IList<V, number>'.
  Property 'has' is missing in type '{}'.
src/factory.ts(10,51): 2345 Argument of type 'V' is not assignable to parameter of type '{}[]'.
  Property 'length' is missing in type '{}'.
src/factory.ts(11,14): 2322 Type 'Unit<{}>' is not assignable to type 'IList<V, number>'.
  Types of property 'get' are incompatible.
    Type '(id: number) => {}' is not assignable to type '(id: number) => V'.
      Type '{}' is not assignable to type 'V'.
src/factory.ts(9,30):2322类型“V”不可分配给类型“IList”。
类型“{}”中缺少属性“has”。
src/factory.ts(10,51):类型为“V”的2345参数不能分配给类型为“{}[]”的参数。
类型“{}”中缺少属性“length”。
src/factory.ts(11,14):2322类型“Unit”不可分配给类型“IList”。
属性“get”的类型不兼容。
类型'(id:number)=>{}'不可分配给类型'(id:number)=>V'。
类型“{}”不可分配给类型“V”。
我不确定如何解决这个问题:当然,我可以简单地将方法的返回类型声明为
any
,但这是不可接受的,因为它会导致其他地方的键入问题


有人知道我应该如何继续吗?

请记住,实现签名不可见。当一个方法上有一组重载时,外部只能看到非实现的签名:

// Visible to callers
export default function factory<V,I>(obj: IList<V,I>): IList<V,I>;
// Visible to callers
export default function factory<V>(obj: V[]): IList<V,number>;
// *Not* visible to callers
export default function factory<V>(obj: V): IList<V,number> {
  if(isList(obj)) return obj;
  if(Array.isArray(obj)) return new ArrayList(obj);
  return new Unit(obj);
}
//对调用方可见
导出默认函数工厂(obj:IList):IList;
//对呼叫者可见
导出默认函数工厂(obj:V[]):IList;
//*对呼叫者不可见*
导出默认函数工厂(obj:V):IList{
if(isList(obj))返回obj;
if(Array.isArray(obj))返回新的ArrayList(obj);
返回新单元(obj);
}
最后一个签名需要是它自己的重载,如下所示

// Visible to callers
export default function factory<V,I>(obj: IList<V,I>): IList<V,I>;
// Visible to callers
export default function factory<V>(obj: V[]): IList<V,number>;
// Visible to callers
export default function factory<V>(obj: V): IList<V,number>;
// Not seen by callers, so 'any' does not leak out
export default function factory(obj: any): any {
  if(isList(obj)) return obj;
  if(Array.isArray(obj)) return new ArrayList(obj);
  return new Unit(obj);
}
//对调用方可见
导出默认函数工厂(obj:IList):IList;
//对呼叫者可见
导出默认函数工厂(obj:V[]):IList;
//对呼叫者可见
导出默认函数工厂(obj:V):IList;
//来电者看不到,所以“任何”都不会泄露出去
导出默认功能工厂(对象:任意):任意{
if(isList(obj))返回obj;
if(Array.isArray(obj))返回新的ArrayList(obj);
返回新单元(obj);
}
因为调用方无论如何都看不到实现签名,所以现在是使用
any
的好时机,因为类型检查将是一种麻烦而不是帮助