生成部分功能的类型

时间:2018-05-20 16:23:35

标签: typescript generics typescript-typings typescript-generics

我有一个声明类型的函数。我打算使用这个功能的部分版本。但我需要首先为部分版本声明变量。

我可以复制签名,省略第一个参数 虽然它可以工作并进行类型检查,但我想自动执行此操作。

这就是我想要的方式:

function myFunc(a: number, b: number): number {
    return a + b
}

let partFunc: PartialFunc<typeof myFunc>

// later
partFunc = (b) => myFunc(42, b)

我不知道是否可以创建PartialFunc<Func>通用。

我试过这种方法

interface Func1<T1, TRes> {
    (a: T1): TRes
}
interface Func2<T1, T2, TRes> {
    (a: T1, b: T2): TRes
}
interface PartialFunc<TFunc extends Func2<T1, T2, TRes>, T1=any, T2=any, TRes=any> extends Func1<T2, TRes>{}

或与通用类型相同:

type F1<T1, TRes> = (a: T1) => TRes
type F2<T1, T2, TRes> = (a: T1, b: T2) => TRes
type PF<Func extends F2<T1, T2, TRes>, T1=any, T2=any, TRes=any> = F1<T2, TRes>

但这仍然需要我指定所有类型:

let partFunc: PF<typeof myFunc, number, number, number>

否则我有any种类型。

虽然这会强制执行类型检查,例如它不接受PF<typeof myFunc, number, number, string>,我想避免再次写类型。

基本上我想对TS 说出这个函数的签名并删除第一个参数

有没有解决方案?

此任务的上下文 - 我有一个react-redux应用程序,我想将参数从商店绑定到操作调度程序。

1 个答案:

答案 0 :(得分:4)

在TypeScript 2.8及更高版本中,您可以使用conditional types来执行此操作,方法是利用强大的type inference in conditional types功能。以下是您在这种特殊情况下如何使用它的方法:

type RemoveFirstParamFromTwoParamFunction<F extends (a: any, b: any)=>any> =
  F extends (a: any, b: infer B) => infer R ? (b: B) => R : never

function myFunc(a: number, b: number): number {
    return a + b
}

let partFunc: RemoveFirstParamFromTwoParamFunction<typeof myFunc>;
partFunc = (b) => myFunc(42, b);

请注意,这仅适用于两个必需参数的具体功能。如果你需要它来处理更多/更少可能可选参数的可能通用函数,你将需要更加努力地通过枚举案例和彻底测试来完成它。这是因为当前TypeScript(从TypeScript 2.8开始)缺少a way to programmatically access function parameters。您需要的RemoveFirstParam<>的确切类型取决于您的使用案例。

希望有所帮助。祝你好运。

相关问题