打字稿:扩展现有功能定义

时间:2020-05-14 19:29:58

标签: typescript

是否可以基于现有的函数定义来创建新的函数定义?

例如,我有一个具有以下两个功能的第三方库:

  col1 col2  freq
0    B    A     0
1    B    C     1
2    A    B     1
3    A    B     2
4    A    C     3
5    B    A     4

我有一个用JS编写的函数,但是最近被要求添加Typescript定义。我的函数如下所示:

declare function v1(s: string, t: string): string;
declare function v2(n: number): string;

我想做的就是获取现有的v1和v2声明,并像这样以自己的方式使用它们:

function useId(version, ...args) {
    return generators[version](...args);
}

我无法找到满足此特定需求的任何高级类型,但想在采用更长的冗长路径添加我的函数定义之前进行检查(假设它们将重复出现,并且前面带有一个新参数)。 / p>

1 个答案:

答案 0 :(得分:2)

与问题“ Is there ArgumentsType<T> like ReturnType<T> in Typescript?”一样,您可以使用Parameters<T> and ReturnType<T>来引用已知函数T的参数和返回类型。如果您使用该类型键入...args参数,它将在您的签名中包含这些参数。

declare function useId(v: "v1", ...args: Parameters<typeof v1>):
    ReturnType<typeof v1>;
declare function useId(v: "v2", ...args: Parameters<typeof v2>):
    ReturnType<typeof v2>;

useId("v1", "s", "t");
useId("v2", 9001);

如果反复执行此操作,则可以使用可调用的接口类型来表示重载。 (否则,可能很难将重载指定为并集,如问题Overloaded function type in typescript所示。)如果您需要做很多事情,我想您甚至可以使用映射类型或其他技巧来表示两者之间的关系。您的包装器和原始功能。

interface WrapperInterface<
    V1 extends (...args: any) => any,
    V2 extends (...args: any) => any> {
  (version: "v1", ...args: Parameters<V1>): ReturnType<V1>;
  (version: "v2", ...args: Parameters<V2>): ReturnType<V2>;
}

declare const useId2: WrapperInterface<typeof v1, typeof v2>;

useId2("v1", "s", "t");
useId2("v2", 9001);

typescript playground