【问题标题】:Typescript generics, unknown nested function param打字稿泛型,未知的嵌套函数参数
【发布时间】:2019-07-30 16:21:00
【问题描述】:

我对具有未知参数的函数作为参数的通用函数有一些问题。

export const inject = <I,V>(fn:<U>(input?:U) => V, resolveWithPayload: boolean, resolveArgs?: I) => <R>(payload:R):R => {
    resolveWithPayload ? fn(payload) : resolveArgs ? fn(resolveArgs) : fn();
    return  payload;
};

const fn = (value:number):number => {
    propertyToMutate = value;
    return propertyToMutate;
}

const res =_fish.inject(fn,false,60)(50);
but calling it ends with :

'(value: number) => number' 类型的参数不可分配给 '(input?: U) => number' 类型的参数。参数类型 “值”和“输入”不兼容。类型“U”不可分配 输入“数字”。

如果我以这种方式更改代码:

export const inject = <I,V,U>(fn:(input?:U) => V, resolveWithPayload: boolean, resolveArgs?: I) => <R>(payload:R):R => {
    resolveWithPayload ? fn(payload) : resolveArgs ? fn(resolveArgs) : fn();
    return  payload;
};

它以注入本身的类型定义错误结束,例如:

TS2345:“R”类型的参数不可分配给类型参数 'U'。

TS2345:“I”类型的参数不能分配给类型参数 'U'。

如果我不知道“fn”的输入类型,我该怎么办?

谢谢

【问题讨论】:

    标签: typescript generics


    【解决方案1】:

    第一个错误是因为 inject 需要一个签名为 &lt;U&gt;(input?: U) =&gt; V 的函数,但您提供的函数签名为 (value: number) =&gt; number。换句话说,inject 期望 fn 是类型为 U 的泛型函​​数,它接受 U | undefined 类型的参数,但您传递给它的 fn 接受 number 类型的参数.

    很难知道你到底想用所有这些泛型来完成什么,但也许你正在寻找这样的东西:

    export const inject = <U>(fn:(input?:U) => U, resolveWithPayload: boolean, resolveArgs?: U) => (payload:U):U => {
        resolveWithPayload ? fn(payload) : resolveArgs ? fn(resolveArgs) : fn();
        return payload;
    };
    
    const fn = (value:number = 0):number => {
        propertyToMutate = value;
        return propertyToMutate;
    }
    

    注意number 是唯一需要的类型参数

    【讨论】:

    • ok thx,现在我明白了,我错误地推断 fn:(input?:U),它不仅推断 U 的值,而且还作为输入期望的通用函数。我在这里有一个问题, 有什么意义,为什么不只是
    • @OndrejBasista 抱歉,我的编辑器通常配置为支持 React/tsx,它无法解析通用 lambda(如 here 所述)。我仅在测试我的解决方案时才使用该语法并忘记将其删除。为了保持一致性,我已经更新了我的答案。
    • ok thx,我在这里还有一个注意事项,如果我们只使用一个通用 U,我认为结果 U 将在两个返回中都不是有效负载类型,而是首先推断出 U 类型,在这个fn 函数返回类型的案例编号原因..
    • @OndrejBasista 我不确定您打算如何使用inject,但您忽略了fn 的返回值,它可能是(input?:U) =&gt; void。您可以使用payloadresolveArgs 来调用它,因此您可以将其写为&lt;U, V&gt;(fn:(input?:U|V) =&gt; void, resolveWithPayoad:boolean, resolveArgs?:U) =&gt; (payload:V) =&gt; V——但这对于类型推断来说不是很“自然”,因此您最终可能不得不显式指定您的类型参数无论何时调用它。
    猜你喜欢
    • 2020-12-22
    • 2021-12-20
    • 1970-01-01
    • 2021-09-10
    • 2023-02-22
    • 2022-11-11
    • 2018-05-02
    • 2021-02-15
    • 1970-01-01
    相关资源
    最近更新 更多