打字稿:过滤掉休息参数

时间:2020-12-27 14:07:55

标签: typescript

我想从元组中动态删除类型number(元组从函数参数中获取),但数字可以是一个rest类型:

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

我有一个通过递归过滤整个元组的类型:

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;

它适用于简单类型:

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

但是当一个 rest 类型出现在一个元组中时,它的类型不会过滤“数字”或“数字[]”:

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

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

Playground

可能是什么问题以及如何解决?

rest 参数有不同的类型吗?

为什么他通过“extends”通过“any”或“number[]”过滤器检查?

1 个答案:

答案 0 :(得分:1)

你非常接近:

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>; // []

我已经用空数组 T 替换了你最后的返回类型 []

Rest 元素必须在元组的最后。