/** * Filters out all members of {@link T} that are not {@link P} * @param T - Items to filter * @param P - Type to filter out * @returns Filtered items * @example * type Result = Filter<['a', 'b', 'c'], 'b'> * // ^? type Result = ['a', 'c'] */ export type Filter< T extends readonly unknown[], P, Acc extends readonly unknown[] = [], > = T extends readonly [infer F, ...infer Rest extends readonly unknown[]] ? [F] extends [P] ? Filter : Filter : readonly [...Acc]; /** * Makes attributes on the type T required if TRequired is true. * @example * MaybeRequired<{ a: string, b?: number }, true> * => { a: string, b: number } * * MaybeRequired<{ a: string, b?: number }, false> * => { a: string, b?: number } */ export type MaybeRequired = TRequired extends true ? Required : T; /** * Combines members of an intersection into a readable type. * @see {@link https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=NdpAcmEFXY01xkqU3KO0Mg} * @example * Prettify<{ a: string } & { b: string } & { c: number, d: bigint }> * => { a: string, b: string, c: number, d: bigint } */ export type Prettify = { [K in keyof T]: T[K]; } & {}; export type OneOf< union extends object, fallback extends object | undefined = undefined, /// keys extends KeyofUnion = KeyofUnion, > = union extends infer Item ? Prettify< Item & { [_K in Exclude]?: fallback extends object ? // @ts-ignore fallback[_K] : undefined; } > : never; type KeyofUnion = type extends type ? keyof type : never;