[英]Typescript: Infer type for parameter of passed function
我需要能夠根據已知類型的另一個參數推斷作為參數傳遞的函數的參數類型。 這有點難以解釋,所以我寫了一個小演示 ,轉載於此:
interface UnaryFunction<In, Out> {
(arg: In): Out
}
interface WithNumber<In, Out> extends UnaryFunction<In, Out> {
num: number
}
function testExtends<Arg, Fn extends UnaryFunction<Arg, any>>(arg: Arg, fn: Fn): Fn {
return fn;
}
function testInferred<Arg, Out>(arg: Arg, fn: UnaryFunction<Arg, Out>): typeof fn {
return fn
}
function mapWithCaller<From, To>(morphism: UnaryFunction<From, To>): WithNumber<From, To> {
return Object.assign((x: From) => morphism(x), {num: 5})
}
// Error: property length does not exist
testExtends('1', mapWithCaller(x => x.length)).num
// Error: property num does not exist
testInferred('1', mapWithCaller(x => x.length)).num
如您所見,使用testExtends
保留函數的返回類型,而使用testInferred
推斷傳遞函數的參數類型。
我需要能夠結合兩者的優點,這讓我發瘋,這根本不可能嗎? 這是一個錯誤嗎? 按設計?
testInferred
的返回類型的問題是相當明顯的 - 它是非泛型的,並且返回類型是完全固定在UnaryFunction
testExtends
的問題更復雜。 這里的根本原因是你需要mapWithCaller
的參數由一個能夠為參數提供上下文類型的函數類型進行上下文類型化 。
你實際上有一個稍微間接的上下文類型,因為mapWithCaller
本身是通用的,但是因為提供了testInferred
的另一個參數,並且TypeScript可以將testInferred
的預期返回類型mapWithCaller
回其參數,所以這不是問題。
無論如何, testInferred
在這里工作,因為UnaryFunction<In, Out>
是一個具有單個調用簽名的非泛型函數類型。
為什么testExtends
不適用於此? 因為基於extends
子句中的綁定將上下文類型應用於參數是不安全的。 考慮這個調用,這是合法的(除了lambda表達式中的錯誤):
interface OtherFunction<Out> {
(arg: string | number): Out
}
testExtends<string, OtherFunction<number>>('1', mapWithCaller(x => x.length));
基於此處的合法通用實例化 , 允許 mapWithCaller
將number
傳遞給其回調。 TypeScript不能真正假設在一個位置給定一個字符串參數,函數表達式的正確推斷邊界就是這樣。
我不認為有辦法在這里編寫函數聲明,以保留你想要的兩種行為,但我可能是錯的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.