使用 TypeScript 从函数参数的开头删除项目

Remove items from beginning of function arguments with TypeScript

我正在尝试创建一个泛型,它可以从函数的参数列表中删除第一个 n 项。所以说我有这种描述函数的类型:

type Fn = (p1: string, p2: number, p3: boolean) => void;

我可以通过以下方式轻松获取参数:

type Params = Parameters<Fn>;

在另一个函数中,我想重用 Fn 类型的参数,但能够删除前两个。我通过以下方式完成:

type RemoveFirstTwo<T extends unknown[]> = ((...x: T) => void) extends (h: infer A, j: infer B, ...t: infer R) => void ? R : never;

function bar(...rest: RemoveFirstTwo<Params>) {}

bar(true); // ok
bar('', 0, true); // error

看着我的 RemoveFirstTwo 泛型,我觉得我可以让它更泛化一点,但很难。我的想法是制作一个 RemoveFirstNItems 泛型并像这样使用它:

function bar(...rest: RemoveFirstNItems<Params, 2>) {}

我很难用更通用的通用代码替换我的硬编码通用代码。

我在 TS Playground 中创建了上面的内容。

感谢您观看!

解决这个问题的一种方法是定义额外的通用参数来存储删除的项目(默认为空数组)并递归地向其中添加删除的项目,直到它获得所需数量的项目:

type RemoveFirstNItems<T extends unknown[], N extends number, Removed extends unknown[] = []> = 
    Removed['length'] extends N 
        ? T 
        : T extends [infer First, ...infer Rest] 
            ? RemoveFirstNItems<Rest, N, [...Removed, First]> 
            : never;

Playground