强制两个函数在 TypeScript 中采用相同的参数类型

Tru*_*ill 0 typescript typescript-generics

我想创建一个通用函数,它将两个函数作为参数并返回结果。我希望类型强制两个函数具有相同的签名,但不是该签名什么(返回类型除外)。

我可以这样定义类型:

type Func<TResult> = (...args: any[]) => TResult;

function foo<TResult>(f: Func<TResult>, g: Func<TResult>): TResult { ... }
Run Code Online (Sandbox Code Playgroud)

这允许所需的参数:

function f1(s: string, i: number): boolean { return true; }
function g1(s: string, i: number): boolean { return false; }
foo<boolean>(f1, g1);
Run Code Online (Sandbox Code Playgroud)

不幸的是,它还允许具有不同签名的函数:

function g2(b: boolean): boolean { return false; }
foo<boolean>(f1, g2);
Run Code Online (Sandbox Code Playgroud)

是否可以允许前一个调用编译但不允许后者编译?

请注意,我希望它适用于任何参数列表(空、一个参数、两个参数等),但两个函数的参数类型应该匹配。

Tit*_*mir 5

您可以为参数添加其他类型参数,并在剩余参数中使用元组将其传播到函数签名。这将确保两个函数的参数类型相同(或至少兼容)

type Func<TParams extends any[], TResult> = (...args: TParams) => TResult;

function foo<TParams extends any[], TResult>(f: Func<TParams, TResult>, g: Func<TParams, TResult>): TResult {
    return null!
}

function f1(s: string, i: number): boolean { return true; }
function g1(s: string, i: number): number { return 0; }
foo(f1, g1);


function g2(b: boolean): boolean { return false; }
foo(f1, g2);
Run Code Online (Sandbox Code Playgroud)

游乐场链接