ts-reset icon indicating copy to clipboard operation
ts-reset copied to clipboard

Get tuple back from filter(Boolean)

Open Flammae opened this issue 1 year ago • 0 comments

Currently calling the filter(Boolean) method on a tuple turns it into an array of union:

let tuple = ["foo", undefined, "bar", 0] as const;
tuple.filter(Boolean) // ("foo" | "bar")[] 

We can enhance the function to instead return the filtered tuple:

interface ReadonlyArray<T> {
  filter(
    predicate: BooleanConstructor,
    thisArg?: any,
  ): FilterNonFalsy<this>;
}

type FilterNonFalsy<T> = T extends readonly [infer F, ...infer R]
  ? F extends false | 0 | "" | null | undefined | 0n
    ? FilterNonFalsy<R>
    : [F, ...FilterNonFalsy<R>]
  : [];

outputs:

(["1", "2", undefined] as const).filter(Boolean) // now: ["1" | "2"] prev: ("1" | "2")[]

([0, null, undefined, false, ""] as const).filter(Boolean) // now: [] prev: never[]

The order of values in a tuple will most definitely be maintained with this method

Flammae avatar Jan 29 '24 13:01 Flammae