logo hsb.horse
← Voltar para o índice de snippets

Snippets

Função Auxiliar de Extração de Propriedades

Gera uma função que extrai apenas propriedades especificadas de um objeto. Consolida a extração de propriedades type-safe em uma linha para transformações mapBy aninhadas e arrays.

Publicado: Atualizado:

Ao transformar arrays com map, é comum precisar apenas de propriedades específicas em vez do objeto inteiro. Escrever isso inline pode ser verboso, mas definir uma função de extração de propriedades antecipadamente permite expressões concisas como map(propsExtractor('id', 'name')).

Código

type LiteralObject = Record<string, unknown>
/**
* Gera uma função que extrai apenas propriedades especificadas de um objeto
*/
export function propsExtractor<
Props extends LiteralObject,
PropKey extends keyof Props,
>(
...props: PropKey[]
): (obj: Props) => Pick<Props, PropKey> {
return (obj: Props) => {
const result: Partial<Props> = {}
for (const prop of props) {
if (Object.hasOwn(obj, prop)) {
result[prop] = obj[prop]
}
}
return result as Pick<Props, PropKey>
}
}

Uso

type User = {
id: string
name: string
email: string
role: string
createdAt: Date
}
const users: User[] = [
{ id: '1', name: 'Alice', email: 'alice@example.com', role: 'admin', createdAt: new Date() },
{ id: '2', name: 'Bob', email: 'bob@example.com', role: 'user', createdAt: new Date() },
]
// Extrair apenas ID e nome
const userSummaries = users.map(propsExtractor('id', 'name'))
// => [{ id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }]
// Funciona bem mesmo em maps aninhados
const departments = [
{ name: 'Engineering', members: users },
{ name: 'Sales', members: users },
]
const summaries = departments.map(dept => ({
department: dept.name,
members: dept.members.map(propsExtractor('id', 'name'))
}))

Como Funciona

  1. propsExtractor aceita nomes de propriedades para extrair como argumentos variádicos
  2. Retorna uma função do tipo (obj: Props) => Pick<Props, PropKey> como closure
  3. A função retornada verifica a existência da propriedade com Object.hasOwn antes de extrair
  4. O tipo utilitário Pick do TypeScript garante inferência de tipo precisa para o valor de retorno

Usar Object.hasOwn garante segurança ao não extrair erroneamente propriedades da cadeia de protótipos.

Benefícios

  • Legível: A intenção é clara com expressões como map(propsExtractor('id', 'name'))
  • Type-safe: A inferência de tipo do TypeScript determina com precisão o tipo extraído
  • Reutilizável: Defina uma vez, use em vários locais
  • Lida bem com aninhamento: Mantém a legibilidade mesmo com múltiplas aplicações de mapBy

Cuidados

Propriedades que não existem não são incluídas no resultado (nem mesmo como undefined). Se você quiser incluir todas as propriedades, remova a verificação Object.hasOwn. Além disso, se estiver extraindo muitas propriedades, definir explicitamente uma interface pode ser mais sustentável.

Aplicações

  • Extrair apenas campos necessários de respostas de API antes de retornar aos clientes
  • Excluir propriedades contendo informações sensíveis durante o logging (criar uma versão de filtro inverso)
  • Extrair estado parcial em seletores Redux ou Zustand
  • Implementar lógica de recuperação parcial semelhante à seleção de campos GraphQL