gpt4 book ai didi

typescript :推断传递函数参数的类型

转载 作者:搜寻专家 更新时间:2023-10-30 21:08:10 26 4
gpt4 key购买 nike

我需要能够根据类型已知的另一个参数推断作为参数传递的函数的参数类型。有点难以解释所以我写了一个 little demo ,转载于此:

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 可以路由 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 不能真正假设给定一个位置的字符串参数,函数表达式的正确推断边界就是这样。

我不认为有一种方法可以在此处以保留您想要的两种行为的方式编写函数声明,但我可能是错的。

关于 typescript :推断传递函数参数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50478100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com