//#region src/types/helper.d.ts type IsAny = 0 extends 1 & T ? true : false; type Prettify = Omit; type PrettifyDeep = { [K in keyof T]: T[K] extends ((...args: any[]) => any) ? T[K] : T[K] extends object ? T[K] extends Array ? T[K] : T[K] extends Date ? T[K] : PrettifyDeep : T[K] } & {}; type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; type RequiredKeysOf = Exclude<{ [Key in keyof BaseType]: BaseType extends Record ? Key : never }[keyof BaseType], undefined>; type HasRequiredKeys = IsAny extends true ? false : [BaseType] extends [object] ? RequiredKeysOf extends never ? false : true : false; type StripEmptyObjects = { [K in keyof T]: T[K] }; /** * Object merge replacing `Base`'s keys with `Override`'s. * The naive `Omit & Override` form breaks under generics. * * @see https://github.com/microsoft/TypeScript/issues/57466#issuecomment-1957988380 */ type OverrideMerge = Base extends unknown ? Override extends unknown ? Prettify<{ [K in keyof Base as K extends keyof Override ? never : K]: Base[K] } & Override> : never : never; /** * Extracts a Record-typed field from a plugin, guarding against `any`. */ type ExtractPluginField = IsAny extends true ? {} : T extends { [K in Field]?: Record } ? T[Field] extends Record ? T[Field] : {} : {}; /** * Walks a plugin tuple with tail-recursive accumulator (TS 4.5+), * extracting and intersecting the given field from each element. */ type InferPluginFieldFromTuple = T extends readonly [infer Head, ...infer Tail] ? InferPluginFieldFromTuple> : Acc; //#endregion export { ExtractPluginField, HasRequiredKeys, InferPluginFieldFromTuple, IsAny, OverrideMerge, Prettify, PrettifyDeep, RequiredKeysOf, StripEmptyObjects, UnionToIntersection };