2014-01-06 37 views
2

这里是我的设置:如何在TypeScript中将eta-reduced泛型函数作为参数传递?

export interface Promised <d, e> { 
    then<o, e>(
     haveData: (data: d) => o, 
     haveError?: (error: e) => e 
     ): Promised<o, e>; 
} 
export interface Problem { 
    message: string; 
} 
export interface Nothing { 
} 
export function ignore<a>(value: a): a { return value; } 
export var nothing: Nothing = {}; 
export function fail<a>(problem: Problem): a; 
export function fail<a>(message: string): a; 
export function fail(something: any): any { 
    if (typeof something === 'string') { 
     throw new Error(something); 
    } else { 
     throw new Error(something.message); 
    } 
}; 

我需要的是ignoreOrFail功能下面写:

export function ignoreOrFail<d>(promise: Promised<d, Problem>): Nothing { 
    promise.then(ignore, fail); // <--- PROBLEM WITH 'fail' 
    return nothing; 
} 

但是它打破了,因为fail函数的类型参数无法推断出可以:

Supplied parameters do not match any signature of call target: 
    Call signatures of types 'typeof fail' and '(error: Problem) => Problem' are incompatible: 
     Type '{}' is missing property 'message' from type 'Problem'. 
     Type '{}' is missing property 'message' from type 'Problem'.  

这可以如果我定义其中类型参数是硬编码的另一种方法是固定的:

export function failAlong(problem: Problem): Problem { 
    return fail<Problem>(problem); 
}; 
export function ignoreOrFail<d>(promise: Promised<d, Problem>): Nothing { 
    promise.then(echo, failAlong); // <---- WORKS THIS WAY 
    return nothing; 
} 

但这是一种愚蠢的事情,不是吗?我认为会起作用的是给编译器一个这样的提示:

export function ignoreOrFail<d>(promise: Promised<d, Problem>): Nothing { 
    promise.then(echo, fail<Problem>); 
    return nothing; 
} 

但是这似乎超出了语法。所以这个问题:有没有一种方法可以将eta-reduced通用函数指定为参数? PS: 对于非泛型函数它不是一个问题(看ignore)。

回答

1

不支持您请求的语法,如下面的段所示。你可以在这里发出一个请求(http://typescript.codeplex.com/workitem/list/basic

function foo<x>(arg:x){} // foo is x=>x  
function bar(arg:(a:number)=>number){} // arg is number=>number 

bar(foo<number>); // Syntax not supported  
bar(foo); // This does work though 

但是你不应该在简单的情况下,得到一个错误,如上图所示。您遇到错误的原因是因为您已经确定了类型参数a

PS:

declare function foo<x>(arg:number):x; // foo is number=>x  
function bar(arg:(a:number)=>number){} // arg is number=>number  
bar(foo); // FAIL 
:这个问题的简单再现
相关问题