{"id":232163,"date":"2023-01-08T11:52:00","date_gmt":"2023-01-08T08:52:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=232163"},"modified":"2022-11-10T07:53:05","modified_gmt":"2022-11-10T04:53:05","slug":"typescript-propriedades-selecionadas-opcionais-com-partial-omit","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/typescript-propriedades-selecionadas-opcionais-com-partial-omit\/","title":{"rendered":"TypeScript: propriedades selecionadas opcionais com Partial &#038; Omit"},"content":{"rendered":"\n<p>Quando voc\u00ea usa o utilit\u00e1rio <code>Partial<\/code>em um tipo, todas as propriedades de tipo s\u00e3o opcionais. Vamos ver como podemos compor este utilit\u00e1rio com outro, <code>Omit<\/code>, para tornar opcionais apenas algumas propriedades deste tipo. Finalmente, criaremos um tipo de utilit\u00e1rio usando gen\u00e9ricos do TypeScript para aplicar isso em qualquer tipo que desejarmos.<\/p>\n<h2>Tornar todas as propriedades de um tipo opcionais<\/h2>\n<p>Os utilit\u00e1rios <code>Partial<\/code>e <code>Omit<\/code>s\u00e3o bem conhecidos no dom\u00ednio <a href=\"https:\/\/startfunction.com\/tag\/typescript\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">TypeScript<\/a> porque s\u00e3o muito \u00fateis para aplic\u00e1-los rapidamente a um tipo e obter o que \u00e9 basicamente um novo tipo. <code>Partial&lt;T&gt;<\/code>converter\u00e1 todas as chaves de um tipo para serem opcionais. Se por exemplo voc\u00ea tem este tipo:<\/p>\n<pre><code>interface Band {\n    lead: string\n    guitar: string\n    bass: string\n    drums: string\n    keyboard: string\n}<\/code><\/pre>\n<p>todas as propriedades s\u00e3o necess\u00e1rias quando algo tem esse tipo. Se voc\u00ea quiser atribuir um objeto como este:<\/p>\n<pre><code>const FooFighters: Band = {\n    lead: 'Dave Grohl',\n    guitar: 'Pat Smears',\n    bass: 'Nate Mendel',\n    drums: 'Taylor Williams',\n}<\/code><\/pre>\n<p>ele falhar\u00e1 porque est\u00e1 faltando a <code>keyboard<\/code>propriedade. Agora, poder\u00edamos marcar essa propriedade como opcional e o TypeScript nos permite fazer isso facilmente. A maneira mais b\u00e1sica de fazer isso \u00e9 anexando um ponto de interroga\u00e7\u00e3o ao seu nome. Neste caso, se for poss\u00edvel editar o tipo original, voc\u00ea pode ir at\u00e9 ele e modific\u00e1-lo assim:<\/p>\n<pre><code>interface Band {\n    lead: string\n    guitar: string\n    bass: string\n    drums: string\n    keyboard?: string\n}<\/code><\/pre>\n<p>Excelente. Agora, a atribui\u00e7\u00e3o anterior ser\u00e1 bem-sucedida porque <code>keyboard<\/code>n\u00e3o \u00e9 mais necess\u00e1ria. Mas e se n\u00e3o for poss\u00edvel alterar o tipo original por qualquer motivo? O que voc\u00ea pode fazer rapidamente nesses casos \u00e9 aplicar <code>Partial<\/code>a esse tipo:<\/p>\n<pre><code>type NotAllTheBand = Partial\n\nconst FooFighters: NotAllTheBand = {\n    lead: 'Dave Grohl',\n    guitar: 'Pat Smears',\n    bass: 'Nate Mendel',\n    drums: 'Taylor Williams',\n}<\/code><\/pre>\n<p>Isso interrompe a imposi\u00e7\u00e3o de todas as propriedades, tornando-as opcionais. Talvez \u00e0s vezes queiramos isso, mas e se quisermos apenas tornar opcional apenas uma propriedade e evitar modificar o tipo original?<\/p>\n<h2>Removendo propriedades de um tipo<\/h2>\n<p>Antes de passarmos para ele e ver como ele funciona, vamos ver outro utilit\u00e1rio que nos ajudar\u00e1 com isso: <code>Omit<\/code>. Esse tipo de utilit\u00e1rio remove as propriedades do tipo em que \u00e9 aplicado. Enquanto <code>Partial<\/code>n\u00e3o recebe outros argumentos al\u00e9m do tipo, <code>Omit<\/code>recebe o tipo mais as propriedades que voc\u00ea deseja remover: <code>Omit&lt;T, K&gt;<\/code>.<\/p>\n<p>N\u00e3o \u00e9 como se <code>Partial<\/code>isso os tornasse opcionais: <code>Omit<\/code>os eliminar\u00e1 completamente do tipo. Quando voc\u00ea usa <code>Partial&lt;Band&gt;<\/code>\u00e9 como se voc\u00ea tivesse feito isso:<\/p>\n<pre><code>interface Band {\n    lead?: string\n    guitar?: string\n    bass?: string\n    drums?: string\n    keyboard?: string\n}<\/code><\/pre>\n<p>No entanto, quando voc\u00ea usa <code>Omit&lt;Band, 'keyboard'&gt;<\/code>, \u00e9 como se voc\u00ea tivesse feito isso:<\/p>\n<pre><code>interface Band {\n    lead: string\n    guitar: string\n    bass: string\n    drums: string\n}<\/code><\/pre>\n<p>Isso agora est\u00e1 come\u00e7ando a fazer sentido, certo? Voc\u00ea pode imaginar o que poder\u00edamos fazer no TypeScript se tiv\u00e9ssemos um tipo que tivesse todas as propriedades do original definidas como opcionais e outro tipo que tivesse apenas as propriedades que desejamos exigir? Se ao menos houvesse uma maneira de&#8230; cruzar esses tipos, certo?<\/p>\n<h2>Tipos de interse\u00e7\u00e3o<\/h2>\n<p>Sim, h\u00e1 uma maneira no TypeScript usando o e comercial <code>&amp;<\/code>, o operador de interse\u00e7\u00e3o de tipo. Este operador, dados dois tipos, constr\u00f3i um novo com as propriedades que pertencem a ambos os tipos:<\/p>\n<pre><code>interface SomeType {\n    propA: string\n    propB: number\n}\n\ninterface AnotherType {\n    propC: boolean\n    propD: Array\n}\n\ntype IntersectedType = SomeType &amp; AnotherType\n<\/code><\/pre>\n<p>A esta altura voc\u00ea j\u00e1 deve ter percebido: vamos cruzar um tipo parcializado e um tipo onde removemos algumas de suas propriedades.<\/p>\n<h2>Tornar as propriedades selecionadas de um tipo opcionais<\/h2>\n<p>Vamos tentar dar sentido a isso. \u00c9 importante ao aprender TypeScript racionalizar o que est\u00e1 acontecendo com nossos tipos.<\/p>\n<p>Vamos pegar um tipo que tem todas as suas propriedades definidas como opcionais gra\u00e7as ao <code>Partial<\/code>aplicado nele. Em seguida, vamos cruz\u00e1-lo com um tipo que tem propriedades selecionadas removidas por <code>Omit<\/code>. Vejamos um exemplo:<\/p>\n<pre><code>interface SomeType {\n    propA: string\n    propB: number\n}\n\ntype OptionalPropB = Partial &amp; Omit<\/code><\/pre>\n<p>Agora temos um novo tipo, sem modificar o tipo original, que se parece com o seguinte:<\/p>\n<pre><code>type OptionalPropB = {\n    propA: string\n    propB?: string\n}<\/code><\/pre>\n<p>Isso acontece porque estamos pegando propriedades <code>propA?<\/code>e <code>propB?<\/code>do tipo produzido por <code>Partial<\/code>e cruzando-as com <code>propA<\/code>o tipo produzido por <code>Omit<\/code>.<\/p>\n<h2>Utilit\u00e1rios gen\u00e9ricos do TypeScript<\/h2>\n<p>Ok, agora nosso novo tipo funciona e podemos ter apenas propriedades selecionadas marcadas como opcionais sem modificar o tipo original. No entanto, esta linha<\/p>\n<pre><code>type OptionalPropB = Partial &amp; Omit<\/code><\/pre>\n<p>\u00c9 muito verboso, bastante feio e tedioso para escrever todas as vezes. Mais importante, n\u00e3o funcionar\u00e1 para um tipo diferente, teremos que escrev\u00ea-lo novamente todas as vezes. Podemos torn\u00e1-lo mais curto e bonito, e faz\u00ea-lo funcionar para qualquer tipo? Sim, o TypeScript nos permite usar gen\u00e9ricos aqui e criar nosso pr\u00f3prio tipo de utilit\u00e1rio:<\/p>\n<pre><code>type Optional = Partial &amp; Omit<\/code><\/pre>\n<p>E agora temos nosso pr\u00f3prio tipo de utilit\u00e1rio TypeScript implementado com gen\u00e9ricos que podemos usar para tornar opcionais as propriedades de tipo selecionadas em qualquer tipo. Podemos usar assim:<\/p>\n<pre><code>type TypeWithOptionalProp = Optional<\/code><\/pre>\n<p>Voc\u00ea notar\u00e1 que a assinatura \u00e9 semelhante a Omit: este utilit\u00e1rio usa o tipo para operar e as propriedades que ser\u00e3o opcionais. Se voc\u00ea tiver mais, voc\u00ea pode usar o operador union:<\/p>\n<pre><code>type TypeWithOptionalProps = Optional<\/code><\/pre>\n<h2>Palavras de encerramento<\/h2>\n<p>Agora voc\u00ea pode salvar esse tipo de utilit\u00e1rio gen\u00e9rico em um arquivo e export\u00e1-lo para us\u00e1-lo em todo o aplicativo. Aqui est\u00e1 um <a href=\"https:\/\/www.typescriptlang.org\/play?#code\/JYOwLgpgTgZghgYwgAgMoHsC2EAqBPABxQG8AoZC5AqdAgQQC5kBnMKUAc3MutoCEmIAK6YARtG4VeBAMJNR6dABsIcEKQC+pUqEixEKOiHRgAFtHxFkZSlRr0mrdiC63pc5AuWr1W0mEIUAAU4KDBgOCVLFABeZBCwiKUAHgxsaIA+f0DkAHlMYDBo5Dj8wtSsXECAGmQAcmk+OqyAqwBJcGhmCARIABNiuLSqqwAyZCMTcyho7KtcgnD0EEig+z4S+NDwyIr0wIzkcbKwPZGIWob15u0AelvkHCg8ZCgITHQAN047Wjpaxq1dBQX6yWpgdDIT7QYAwF5mCB4OpvZC0JYrJQAOlICGWrGQkFYAEYmAkdlEcnEbKDGPVREohBA6tVuI0mESAEwAZhZUnsHjYjJZGgA3HcHk8XnA+n0fo0CZDoew4chCnVmK8IABHITAN59bG4kD4wlgDlME6Days+y0ur0xnMm20AVQIWaMWke6PZ6aj7fFw0gHrIEg9zgxUwlUIpEot46vUQA04vFgAkQVhcpgdPTdXpJq3U6R2h1M3mggTITk852yJiCi4e8U+qUyuXrBVQqMvNUatHAZaRbHeyV+r7tv6osP8ztK2E9sDqzUJ-WG1Pp1gAFgtiwHGLW-E2RdtTHtDLLtdd7tFzYA4gBRABy94ASm0ZMgAKo4NoAGTaOAAJoAIRzCgCzorsOC1AA0sgEAAB6QCAfQagA1oi6AwI8hxxGSSTJDghzHAUpzQcgMFZGBjyBAA6oUpgQXuqz2BqpS7oOKTDNElyNHUyAAD71O4NxehKvrSrKgbysCoIfhCXbKvC5ixig-accO4kvG8-oTvQs7dqqi4avGuqrimxppqaACsTDRPRZhMZxB4EGx1p8n8p6lk6opAA\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">link para um playground TypeScript<\/a> onde adicionei o c\u00f3digo deste artigo e comentei para que voc\u00ea possa ver o que est\u00e1 acontecendo, olhando para <code>Partial<\/code>, <code>Omit<\/code>e nosso tipo de utilit\u00e1rio gen\u00e9rico.<\/p>\n<p>O mundo dos gen\u00e9ricos e utilit\u00e1rios \u00e9 fant\u00e1stico no TypeScript. Entre e comece a experimentar!<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/startfunction.com\" class=\"external external_icon\">startfunction.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use Parcial e Omitir para tornar opcionais apenas determinadas propriedades de um tipo.<\/p>\n","protected":false},"author":1,"featured_media":236900,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,753,722,733,846,867],"tags":[1170],"class_list":["post-232163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-codigo-aberto","category-desenvolvedor","category-javascript-8","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/232163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=232163"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/232163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/236900"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=232163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=232163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=232163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}