RequireAtLeastOne type

RequireAtLeastOne ajuda a criar um tipo em que pelo menos uma das propriedades de uma interface (pode ser qualquer propriedade) tem de existir.

Isto funciona devido aos tipos de utilitário do TypeScript: https://www.typescriptlang.org/docs/handbook/utility-types.html Vamos examiná-lo:

  • [K in keyof T]-? esta propriedade (K) só é válida se tiver o mesmo nome que qualquer propriedade de T.
  • Required<Pick<T, K>> cria um novo tipo de T apenas com a propriedade atual na iteração e marca-o conforme necessário
  • Partial<Pick<T, Exclude<keyof T, K>>> cria um novo tipo com todas as propriedades de T, exceto a partir da propriedade K.
  • & é o que une o tipo com apenas uma propriedade necessária de Required<...> com todas as propriedades opcionais de Partial<...>.
  • [keyof T] garante que apenas as propriedades de T são permitidas.
type RequireAtLeastOne<T> = {
  [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>
}[keyof T]