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ê lista | as chaves a manter | as chaves a remover |
Propriedades novas em T | não incluídas | incluídas automaticamente |
Chave desconhecida em K | erro de compilação (TS2344) | aceita em silêncio |
| Bom para | respostas 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.