{"id":231775,"date":"2023-01-08T11:35:00","date_gmt":"2023-01-08T08:35:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231775"},"modified":"2022-12-25T19:00:45","modified_gmt":"2022-12-25T16:00:45","slug":"typescript-propiedades-seleccionadas-opcionales-con-parcial-y-omitir","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/typescript-propiedades-seleccionadas-opcionales-con-parcial-y-omitir\/","title":{"rendered":"TypeScript: propiedades seleccionadas opcionales con Parcial y Omitir"},"content":{"rendered":"\n<p>Cuando usa la utilidad <code>Partial<\/code>en un tipo, har\u00e1 que todas las propiedades del tipo sean opcionales. Veamos c\u00f3mo podemos combinar esta utilidad con otra, <code>Omit<\/code>, para hacer opcionales solo ciertas propiedades de este tipo. Finalmente, crearemos un tipo de utilidad usando gen\u00e9ricos de TypeScript para aplicar esto en cualquier tipo que queramos.<\/p>\n<h2>Hacer que todas las propiedades de un tipo sean opcionales<\/h2>\n<p>Las utilidades <code>Partial<\/code>y <code>Omit<\/code>son bien conocidas en el \u00e1mbito de <a href=\"https:\/\/startfunction.com\/tag\/typescript\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">TypeScript<\/a> porque son muy \u00fatiles para aplicarlas r\u00e1pidamente a un tipo y obtener lo que es b\u00e1sicamente un tipo nuevo. <code>Partial&lt;T&gt;<\/code>convertir\u00e1 todas las claves de un tipo en opcionales. Si por ejemplo tienes 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 las propiedades son requeridas cuando algo tiene este tipo. Si desea asignar un 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>fallar\u00e1 porque le falta la <code>keyboard<\/code>propiedad. Ahora, podr\u00edamos marcar esta propiedad como opcional y TypeScript nos permite hacerlo f\u00e1cilmente. La forma m\u00e1s b\u00e1sica de hacerlo es agregando un signo de interrogaci\u00f3n a su nombre. En este caso, si es posible editar el tipo original, puedes ir a \u00e9l y modificarlo as\u00ed:<\/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. Ahora la asignaci\u00f3n anterior tendr\u00e1 \u00e9xito porque <code>keyboard<\/code>ya no es necesaria. Pero, \u00bfy si no es posible cambiar el tipo original por cualquier motivo? Lo que puedes hacer r\u00e1pidamente en estos casos es aplicar <code>Partial<\/code>a este 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>Esto deja de aplicar todas las propiedades, haci\u00e9ndolas todas opcionales. Tal vez a veces queramos esto, pero \u00bfqu\u00e9 pasa si solo queremos hacer que solo una propiedad sea opcional y evitar modificar el tipo original?<\/p>\n<h2>Quitar propiedades de un tipo<\/h2>\n<p>Antes de pasar a ella y ver c\u00f3mo funciona, veamos otra utilidad que nos ayudar\u00e1 con esto: <code>Omit<\/code>. Este tipo de utilidad elimina propiedades del tipo donde se aplica. Si bien <code>Partial<\/code>no toma otros argumentos adem\u00e1s del tipo, <code>Omit<\/code>toma el tipo m\u00e1s las propiedades que desea eliminar: <code>Omit&lt;T, K&gt;<\/code>.<\/p>\n<p>No es que <code>Partial<\/code>eso los haga opcionales: <code>Omit<\/code>los borrar\u00e1 por completo del tipo. Cuando lo usas <code>Partial&lt;Band&gt;<\/code>es como si hubieras hecho esto:<\/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>Sin embargo, cuando usas <code>Omit&lt;Band, 'keyboard'&gt;<\/code>, es como si hubieras hecho esto:<\/p>\n<pre><code>interface Band {\n    lead: string\n    guitar: string\n    bass: string\n    drums: string\n}<\/code><\/pre>\n<p>Esto ahora est\u00e1 empezando a tener sentido, \u00bfverdad? \u00bfTe imaginas lo que podr\u00edamos hacer en TypeScript si tenemos un tipo que tiene todas las propiedades del original configurado como opcional y otro tipo que tiene solo las propiedades que queremos requerir? Si tan solo hubiera una manera de&#8230; cruzar estos tipos, \u00bfverdad?<\/p>\n<h2>Tipos de intersecci\u00f3n<\/h2>\n<p>S\u00ed, hay una manera en TypeScript usando el ampersand <code>&amp;<\/code>, el operador de intersecci\u00f3n de tipos. Este operador, dados dos tipos, construye uno nuevo con las propiedades propias de ambos 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>Probablemente ya lo haya descubierto: vamos a cruzar un tipo parcializado y un tipo del que eliminamos algunas de sus propiedades.<\/p>\n<h2>Hacer que las propiedades seleccionadas de un tipo sean opcionales<\/h2>\n<p>Tratemos de darle sentido. Al aprender TypeScript, es importante racionalizar lo que sucede con nuestros tipos.<\/p>\n<p>Vamos a tomar un tipo que tenga todas sus propiedades configuradas como opcionales gracias a que <code>Partial<\/code>se le aplic\u00f3. A continuaci\u00f3n, vamos a cruzarlo con un tipo que tiene propiedades seleccionadas eliminadas por <code>Omit<\/code>. Veamos un ejemplo:<\/p>\n<pre><code>interface SomeType {\n    propA: string\n    propB: number\n}\n\ntype OptionalPropB = Partial &amp; Omit<\/code><\/pre>\n<p>Ahora tenemos un nuevo tipo, sin modificar el tipo original, que se parece a lo siguiente:<\/p>\n<pre><code>type OptionalPropB = {\n    propA: string\n    propB?: string\n}<\/code><\/pre>\n<p>Esto sucede porque tomamos propiedades <code>propA?<\/code>y <code>propB?<\/code>del tipo producido por <code>Partial<\/code>y las cruzamos con <code>propA<\/code>el tipo producido por <code>Omit<\/code>.<\/p>\n<h2>Utilidades gen\u00e9ricas de TypeScript<\/h2>\n<p>Bien, ahora nuestro nuevo tipo funciona y solo podemos tener propiedades seleccionadas marcadas como opcionales sin modificar el tipo original. Sin embargo, esta l\u00ednea<\/p>\n<pre><code>type OptionalPropB = Partial &amp; Omit<\/code><\/pre>\n<p>Es demasiado prolijo, bastante feo y tedioso para escribir cada vez. M\u00e1s importante a\u00fan, no funcionar\u00e1 para un tipo diferente, tendremos que escribirlo nuevamente cada vez. \u00bfPodemos hacerlo m\u00e1s corto y m\u00e1s bonito, y que funcione para cualquier tipo? S\u00ed, TypeScript nos permite usar gen\u00e9ricos aqu\u00ed y crear nuestro propio tipo de utilidad:<\/p>\n<pre><code>type Optional = Partial &amp; Omit<\/code><\/pre>\n<p>Y ahora tenemos nuestro propio tipo de utilidad TypeScript implementado con gen\u00e9ricos que podemos usar para hacer que las propiedades de tipo seleccionadas sean opcionales en cualquier tipo. Podemos usarlo as\u00ed:<\/p>\n<pre><code>type TypeWithOptionalProp = Optional<\/code><\/pre>\n<p>Notar\u00e1 que la firma es similar a Omitir: esta utilidad toma el tipo para operar y las propiedades que se har\u00e1n opcionales. Si tiene m\u00e1s, puede usar el operador de uni\u00f3n:<\/p>\n<pre><code>type TypeWithOptionalProps = Optional<\/code><\/pre>\n<h2>palabras de cierre<\/h2>\n<p>Ahora puede guardar este tipo de utilidad gen\u00e9rica en un archivo y exportarlo para usarlo en toda su aplicaci\u00f3n. Aqu\u00ed hay un <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\">enlace a un \u00e1rea de juegos de TypeScript<\/a> donde agregu\u00e9 el c\u00f3digo de este art\u00edculo y lo coment\u00e9 para que pueda ver lo que est\u00e1 pasando, mirando <code>Partial<\/code>, <code>Omit<\/code>y nuestro tipo de utilidad gen\u00e9rica.<\/p>\n<p>El mundo de los gen\u00e9ricos y las utilidades es fant\u00e1stico en TypeScript. \u00a1An\u00edmate y empieza a experimentar!<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <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 y Omitir para hacer opcionales solo ciertas propiedades de un 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":[892,716,747,727,840,861],"tags":[1172],"class_list":["post-231775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-desarrollador","category-fuente-abierta","category-javascript-2","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/231775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=231775"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/231775\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236900"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=231775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=231775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=231775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}