Menu

Pick em TypeScript: selecionar propriedades de um tipo

Pick<T, K> cria um tipo só com as propriedades de T cujas chaves estão em K. Veja Pick com uma ou várias chaves, como ele verifica as chaves, Pick vs Omit, como selecionar de tipos aninhados, uma função pick() tipada e como selecionar propriedades pelo tipo do valor.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Pick<T, K> é um utility type embutido que cria um tipo de objeto só com as propriedades de T citadas em K. Use-o quando uma função ou um componente precisa de alguns campos de um tipo maior:

renderPreview aceita um User completo e também um objeto simples { id, name }, porque pede só o que usa. Isso a torna mais fácil de chamar e de testar. Pick existe só nos tipos: o objeto ada completo continua tendo as cinco propriedades em tempo de execução.

Sintaxe e verificação das chaves

Pick<Type, Keys>

Keys é uma única chave ou uma union de chaves, e cada uma precisa existir em Type. A definição na biblioteca padrão do TypeScript transforma isso em uma restrição:

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

Por causa de K extends keyof T, uma chave escrita errado ou inexistente é erro de compilação, e o seu editor consegue autocompletar os nomes das chaves:

O erro é error TS2344: Type '"cost"' does not satisfy the constraint 'keyof Product'. Essa é uma diferença em relação a Omit, cujas chaves não são verificadas.

Pick mantém readonly e opcional

Pick mapeia sobre chaves de T, então cada propriedade selecionada mantém os seus modificadores:

A última linha mostra { id: 8 } porque readonly é só uma verificação de tempo de compilação: a atribuição foi apontada, suprimida com @ts-expect-error, e ainda assim foi executada. Para mudar os modificadores ao selecionar, envolva o resultado: Partial<Pick<Account, "plan">> ou Required<Pick<Account, "email">>.

Pick vs Omit

Pick diz o que manter; Omit diz o que descartar. Os dois dão o mesmo resultado hoje, mas se comportam de forma diferente quando o tipo de origem cresce:

Pick<T, K>Omit<T, K>
Você listaas chaves a manteras chaves a remover
Propriedades novas em Tnão incluídasincluídas automaticamente
Chave desconhecida em Kerro de compilação (TS2344)aceita em silêncio
Bom pararespostas de API, visões públicas, props"tudo exceto o segredo"

Para dados que saem do seu servidor, Pick é o padrão mais seguro: nada aparece no tipo a menos que alguém o tenha adicionado de propósito.

Selecionando de tipos aninhados

Pick só enxerga as chaves do primeiro nível: um caminho com ponto como Pick<Customer, "address.city"> é erro (TS2344), não uma seleção aninhada. Use um indexed access type para chegar ao tipo aninhado e selecione a partir dele:

Customer["address"] é o tipo da propriedade address. A mesma sintaxe alcança elementos de arrays: para uma propriedade orders: Order[], Customer["orders"][number] é Order.

Uma função pick() tipada

Pick não faz nada em tempo de execução. Uma pequena função genérica copia as propriedades escolhidas para um objeto novo e retorna exatamente Pick<T, K>:

K extends keyof T permite que o TypeScript infira K a partir dos argumentos string, então o tipo de retorno tem exatamente as chaves selecionadas. A assertion {} as Pick<T, K> é necessária porque um objeto vazio ainda não tem essas propriedades; o loop as preenche.

Selecionando propriedades pelo tipo do valor

Pick seleciona pelo nome da chave. Para selecionar pelo tipo da propriedade, por exemplo "todos os campos string", escreva um mapped type com um filtro de chaves:

A cláusula as mapeia cada chave para ela mesma quando o tipo combina e para never caso contrário, e chaves never são descartadas. Um detalhe: o tipo de uma propriedade opcional inclui undefined, então um subtitle?: string opcional não contaria como string aqui; teste contra string | undefined para incluí-lo.

Perguntas frequentes

O que Pick faz no TypeScript?

Pick<T, K> monta um tipo de objeto que contém só as propriedades de T cujas chaves estão em K. Pick<User, "id" | "name"> é { id: number; name: string } quando User tem essas duas propriedades e outras. Ele funciona só com tipos e não remove nada dos objetos em tempo de execução.

Qual a diferença entre Pick e Omit?

Pick lista as propriedades a manter, Omit lista as que devem ser removidas. Quando o tipo de origem ganha uma propriedade, Omit a inclui automaticamente e Pick não. Pick também verifica se as chaves existem no tipo; Omit aceita qualquer chave.

Como selecionar várias propriedades com Pick no TypeScript?

Passe uma union de chaves: Pick<User, "id" | "name" | "email">. Todas as chaves precisam existir em User, senão o compilador mostra o erro TS2344.

Como selecionar uma propriedade aninhada no TypeScript?

Pick só seleciona propriedades do primeiro nível. Chegue ao tipo aninhado com um indexed access type e selecione a partir dele: Pick<User["address"], "city">. Para manter o aninhamento, combine os dois: Pick<User, "id"> & { address: Pick<User["address"], "city"> }.

Pick mantém os modificadores readonly e opcional?

Sim. Pick é um mapped type sobre chaves de T, então uma propriedade que é readonly ou opcional em T continua assim no tipo selecionado.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR