Generics 不确定此Typescript代码中为什么需要强制转换。我的derp,还是语言限制?

Generics 不确定此Typescript代码中为什么需要强制转换。我的derp,还是语言限制?,generics,typescript,bluebird,definitelytyped,Generics,Typescript,Bluebird,Definitelytyped,我正在使用bluebird的打字(DefinitelyTyped)定义,我遇到了Promise.trument的问题 我不明白为什么我需要以下演员阵容: 返回承诺。尝试(()=>{ 返回处理程序(matchResult,id); }); 请注意,处理程序的类型返回Data | Promise。如果不将返回值强制转换为,则会出现以下错误: src/domain.ts(72,50): error TS2345: Argument of type '() => Data | Promise

我正在使用bluebird的打字(DefinitelyTyped)定义,我遇到了
Promise.trument
的问题

我不明白为什么我需要以下演员阵容:

返回承诺。尝试(()=>{
返回处理程序(matchResult,id);
}); 
请注意,处理程序的类型返回
Data | Promise
。如果不将返回值强制转换为
,则会出现以下错误:

src/domain.ts(72,50): error TS2345: Argument of type '() => Data |
Promise<Data>' is not assignable to parameter of type '() => Data'.
  Type 'Data | Promise<Data>' is not assignable to type 'Data'.
    Type 'Promise<Data>' is not assignable to type 'Data'.
src/domain.ts(72,50):错误TS2345:类型为“()=>数据的参数|
承诺“”不可分配给类型为“()=>Data”的参数。
类型“Data | Promise”不可分配给类型“Data”。
类型“Promise”不可分配给类型“Data”。
如果尝试的签名只使用返回数据的函数,但有两个重载,那么这是有意义的

尝试(fn:()=>PromiseLike,args?:any[],ctx?:any):承诺;
尝试(fn:()=>T,args?:any[],ctx?:any):承诺;
我的期望是,Typescript将看到这两种重载,并认识到
()=>数据|承诺
()=>数据
加上
()=>承诺
是相同的,但事实似乎并非如此

我错过什么了吗?这是Typescript的限制还是仅仅是糟糕的类型定义


我可以修改bluebird类型定义,使其具有一个重载,该重载接受
()=>T | Promise
,然后我不需要强制转换,但我仍然想理解为什么在现有重载的情况下有必要这样做。

您的问题还有一个未决问题。:-)

,问题是TypeScript无法自动确定如何分解该联合类型,或如何组合重载,并确保它们在此实例中兼容。实际上,问题在于bluebird的类型定义。而不是有两个重载:

attempt<T>(fn: () => PromiseLike<T>, args?: any[], ctx?: any): Promise<T>;
attempt<T>(fn: () => T, args?: any[], ctx?: any): Promise<T>;
尝试(fn:()=>PromiseLike,args?:any[],ctx?:any):承诺;
尝试(fn:()=>T,args?:any[],ctx?:any):承诺;
它应该改写为

attempt<T>(fn: () => T | PromiseLike<T>, args?: any[], ctx?: any): Promise<T>;
尝试(fn:()=>T | PromiseLike,args?:any[],ctx?:any):承诺;
我已经发出了一些类似的问题

attempt<T>(fn: () => PromiseLike<T>, args?: any[], ctx?: any): Promise<T>;
attempt<T>(fn: () => T, args?: any[], ctx?: any): Promise<T>;
attempt<T>(fn: () => T | PromiseLike<T>, args?: any[], ctx?: any): Promise<T>;