2015-05-04 55 views
0

在我正在处理的库中,我有一种方法可以确保IList类型的东西,如果不是,它会将其变为IList类型的实例。请参见下面的代码:如何在TypeScript中使用泛型重载函数进行类型转换

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 } 

这种方法编译失败,请参阅下面的错误:

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'. 

我不能确定如何解决此问题:当然,我可以简单地声明的返回类型该方法为any,但这是不可接受的,因为这会导致在别处输入问题。

有谁知道我应该如何继续?

回答

2

请记住,执行签名不可见。当你有一组重载的方法,只有实施签名外部看出:

// 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); 
} 

这最后的签名必须是自己的过载,像这样。

// 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); 
} 

由于呼叫者可以看不到实现的签名,无论如何,这是使用any因为类型检查将是更讨厌而不是帮助的好时机。