简体   繁体   中英

Typescript - Filter a generic array type by element type

I have an array of values:

const array = ['b', 'a', 'b', 'a', 'c'] as const;

So the type is:

const array: readonly ["b", "a", "b", "a", "c"]

Now I want to create a type that filters the array, and returns a type of array with only the filtered elements. I've created a FilterArray type, that does the trick, however, the indexes on the array are taken from the first array and not restarted.

type FilterArray<T extends readonly any[], V> = {
    [I in keyof T as [Extract<T[I], V>] extends [never] ? never : I]: T[I];
}

If I filter now on typeof array , I get these results: 过滤结果 filteredArray[3] is also of type 'a', which is correct.

Is it possible to restart the index from 0? Or should I take another approach?

The problem here is that you are using a mapped type with key remapping . Because of the key remapping , the resulting type of FilterArray is not a tuple but an object type with the two properties 1 and 3 .

To get a tuple type as the result, you need a recursive type.

type FilterArray<T extends readonly any[], V> = 
  T extends readonly [infer L, ...infer R]
    ? L extends V
      ? [L, ...FilterArray<R, V>]
      : [...FilterArray<R, V>]
    : []

This type iterates through the array and adds matching elements to the output.

The resulting type would now look like this:

const filteredArray = {} as FilterArray<typeof array, "a">
//    ^? ["a", "a"]

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM