RequireAtLeastOne type
RequireAtLeastOne helps create a type where at least one of the properties of an interface (can be any property) is required to exist.
This works because of TypeScript's utility types: https://www.typescriptlang.org/docs/handbook/utility-types.html Let's examine it:
[K in keyof T]-?
this property (K) is valid only if it has the same name as any property of T.Required<Pick<T, K>>
makes a new type from T with just the current property in the iteration, and marks it as requiredPartial<Pick<T, Exclude<keyof T, K>>>
makes a new type with all the properties of T, except from the property K.&
is what unites the type with only one required property fromRequired<...>
with all the optional properties fromPartial<...>
.[keyof T]
ensures that only properties of T are allowed.
type RequireAtLeastOne<T> = {
[K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>
}[keyof T]