Typescript: Filtrera bort restparameter


Jag vill dynamiskt ta bort typen number från tuplen (tuplen hämtas från funktionsparametrar), men numret kan vara en resttyp:

function myFn(num1: number, text: string, ...nums: number[]): void {}

type Args = Parameters<typeof myFn>; // [number, string, ...number[]] <- Will be using similar result in future examples

Jag har en typ som filtrerar hela tuplen genom rekursion:

type Filter<T extends any[], U> = T extends [] ? [] :
    T extends [infer H, ...infer R] ?
    H extends U ? Filter<R, U> : [H, ...Filter<R, U>] : T;

Och det fungerar bra för enkla typer:

type Args = [number, string, number, Symbol, number];
type Result = Filter<Args, number>; // [string, Symbol];

Men när en vilotyp dyker upp i en tuple, får dess typ inte heller filtrera vare sig "number" eller "number[]":

type Args = [number, string, ...number[]];

type Result1 = Filter<Args, number>; // [string, ...number[]]
type Result2 = Filter<Args, number[]>; // [number, string, ...number[]]

Lekplats

Vad kan problemet vara och hur kan det lösas?

Har restparametrar en annan typ?

Varför passerar han filterkontrollerna för "any" eller "number[]" med "extends"?

Svar #1

Du var mycket nära:

type Args = [number, string, ...number[]];

type Filter<T extends any[], F> = T extends [] ? [] :
    T extends [infer Head, ...infer Tail] ?
    Head extends F ? Filter<Tail, F> : [Head, ...Filter<Tail, F>] : [];

type Result1 = Filter<Args, number>; // [string]
type Result2 = Filter<Args, number[]>; // [number, string]

type Result3 = Filter<Args, number | number[]>; // [string]
type Result4 = Filter<Args, number | number[] | string>; // []

Jag har ersatt din senaste returtyp T med en tom array []

Restelementet måste vara sist i tuplen.