RequireAtLeastOne type

RequireAtLeastOne помогает создать тип, в котором требуется по крайней мере одно из свойств интерфейса (может быть любым свойством).

Это работает из-за типов служебной программы TypeScript: https://www.typescriptlang.org/docs/handbook/utility-types.html рассмотрим его:

  • [K in keyof T]-? это свойство (K) допустимо только в том случае, если оно имеет то же имя, что и любое свойство T.
  • Required<Pick<T, K>> делает новый тип из T только текущим свойством в итерации и помечает его как необходимое.
  • Partial<Pick<T, Exclude<keyof T, K>>> создает новый тип со всеми свойствами T, кроме свойства K.
  • & заключается в том, что объединяет тип только с одним обязательным свойством из Required<...> со всеми необязательными свойствами из Partial<...>.
  • [keyof T] гарантирует, что разрешены только свойства T.
type RequireAtLeastOne<T> = {
  [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>
}[keyof T]