export type ArrayElement<ArrType> = ArrType extends ReadonlyArray<infer ElementType>
  ? ElementType
  : never;

export type ExcludeNull<T> = T extends null ? never : T;

export type ExcludeUndefined<T> = T extends undefined ? never : T;

export type KeysOfObjectOrNull<T> = keyof ExcludeNull<T>;

/** Combines members of an intersection into a readable type. */
// https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=NdpAcmEFXY01xkqU3KO0Mg
export type Evaluate<Type> = { [key in keyof Type]: Type[key] } & unknown

// Keeps in the object type only those properties that have the provided type (e.g only numbers)
export type PickByType<T, X> = Record<
{[K in keyof T]: T[K] extends X ? K : never}[keyof T],
X
>;

// Make some properties of an object optional
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
