Dominando conceptos avanzados en TypeScript

Rate this content
Bookmark

TypeScript no es solo tipos e interfaces. Únete a esta masterclass para dominar características más avanzadas de TypeScript que harán tu código a prueba de balas. Cubriremos tipos condicionales y notación de inferencia, cadenas de plantillas y cómo mapear sobre tipos de unión y propiedades de objetos/arrays. Cada tema se demostrará en una aplicación de muestra que se escribió con tipos básicos o sin tipos en absoluto y juntos mejoraremos el código para que te familiarices más con cada característica y puedas llevar este nuevo conocimiento directamente a tus proyectos.


Aprenderás:- 

- ¿Qué son los tipos condicionales y la notación de inferencia?

- ¿Qué son las cadenas de plantillas?

- Cómo mapear sobre tipos de unión y propiedades de objetos/arrays.

Jiri Lojda
Jiri Lojda
132 min
06 Nov, 2023

Comments

Sign in or register to post your comment.
  • Parmar Tarun
    Parmar Tarun
    SUNY Binghamton
    Hi, when can we have the recording available for this workshop? Thanks
  • Scott Huffman
    Scott Huffman
    Fidelity Investments
    Not sure if anyone is monitoring these comments for questions--my company has disabled access to zoom's chat--but I wanted to ask about this KeyToGuard, and whether there is any ways to break it into smaller, different types to improve readability?

Video Summary and Transcription

La masterclass cubre conceptos avanzados en TypeScript, como tipos estrictos y guardias de tipo. Explora el uso de herramientas de desarrollo y las ventajas de usar TypeScript en el desarrollo de software. La masterclass también profundiza en el mapeo de tipos de unión y tipos de objetos, así como en palabras clave y tipos condicionales. Se discuten las correcciones de errores y la validación de tipos, junto con el análisis recursivo y la validación de entidades. La masterclass concluye con una corrección de errores final y conclusiones clave para usar TypeScript de manera efectiva.

Available in English

1. Introducción a TypeScript y sus Ventajas

Short description:

Te mostraré algunos conceptos avanzados de TypeScript para que te sientas más cómodo usando tipos. Discutiremos las ventajas de usar tipos estrictos, trabajaremos en ejemplos con errores y exploraremos la precisión de los tipos en las API.

Cómo usar TypeScript para contratar empleados en un grupo web Cómo usar TypeScript en un proyecto VSC Cómo alors crear .sush Me gustaría mostrarte algunos conceptos un poco avanzados de TypeScript solo para aclarar algunas cosas y quizás hacerte sentir más cómodo usando estos tipos y ver el valor en ellos.

Hoy estoy aquí con Andrey de Content.ai. Él me ayudará a gestionar las preguntas y el chat. Así que si tienes alguna pregunta, no dudes en preguntar. Y bueno, sí, ese soy yo, puedes contactarme por ejemplo en GitHub puedes ver algunas cosas en las que trabajo. en el contenido de una empresa perfilándolo también y bueno iba a estar en la otra agenda vamos a empezar discutiendo algunas ventajas de usar los tipos estrictos como los tiempos más estrictos que están disponibles para la situación. A continuación, trabajaremos en el primer ejemplo donde habrá un pequeño error en una aplicación que he preparado y hablaremos de cómo un mejor tipado o un mejor uso del sistema de tipos de Typekit podría prevenir tal error y durante eso intentaremos algunos de los conceptos de typeset luego pasaremos a otro ejemplo y luego dependiendo del tiempo y quizás nuestra energía podemos intentar el bonus que he preparado que es un poco más avanzado más sobre jugar con typescript y cosas así veremos si si estás interesado en eso así que primero te mostraré la aplicación en la que estaremos trabajando es solo una simple aplicación de eventos que gestiona algunos eventos que tienes tienes eventos tal vez solo un poco creo que tengo la versión con errores funcionando ahora Así que ejecutaré la otra.

Sí, la aplicación en sí. Quizás solo para detener eso puedes descargarlo desde esta URL. Lo copiaré y pegaré en el chat para que no tengas que buscarlo en la en la pantalla es todo lo demás qué genial gracias por eso y ahora la aplicación debería funcionar sin problemas y como dije es una aplicación muy simple que gestiona algunos eventos, puedes hacer clic en el evento, hay una descripción, sus nombres, puedo crear un nuevo evento, puedo seleccionar un organizador y está ahí. Puedo eliminar eventos, puedo crear eventos para un cierto organizador directamente desde aquí, y puedo copiar eventos. Muy simple. Y sí. Así que continuemos con esto. Entonces, ¿por qué querríamos molestarnos con con tipos y sistema de tipos. Lo que pasa es que a menudo veo que la gente piensa en los tipos como sus enemigos, algo con lo que tienen que luchar y siempre hay obstáculos en su camino. Pero para hacer esto, el sistema de tipos está ahí para ayudarte. Puede encontrar, puede atrapar errores. Realmente puede atrapar muchos errores Y está ahí para respaldarte en caso de que cometas algunos errores de tipeo y errores, esto es muy a menudo. Y también puede ayudarte a explorar las API. Como, a menudo si empiezo con una nueva biblioteca, solo escribo algunas cosas, algunos nombres de funciones y cosas así, y busco tipos, lo que IntelliSense, por ejemplo, me ofrece en mi editor de código. Por ejemplo, si abro este archivo de ejemplo, puedes ver una función, escribir por referencia que acepta un objeto, una referencia, que tiene dos propiedades opcionales, ID y ID externo. Y ahora desde esta API, digo bien, voy a llamar a la función, ¿y qué debería proporcionarle a la función? Bueno, no tengo idea. ¿Debería llamarlo con un objeto vacío? TypeSketch está bien con eso. TypeSketch no puede aconsejarme porque según TypeSketch, esto está bien. Pero probablemente no esté bien porque la referencia es solo un objeto vacío. No hay nada. Probablemente lo que el autor realmente pretendía hacer es decir, bien, quiero que proporciones una ID o una ID externa. Eso es probablemente lo que el autor quiso decir pero no me proporcionó ninguna pauta exacta para eso. Así que estoy perdido aquí. Pero si en cambio hizo algo como esto como esto, bien, quiero un tipo de unión donde quiero que la referencia sea un objeto con una propiedad id que tiene que estar ahí, o otro, o un un objeto diferente que en cambio tiene una propiedad ID externa, que no es opcional y siempre tiene que estar ahí, ahora, la clave de tipo me dice, está bien. El objeto MT no es un parámetro válido para esta función. Necesitas proporcionar un objeto con propiedad ID o propiedad ID externa, pero uno tiene que estar ahí. Y al mismo tiempo, si digo... Esto está bien. Eso es decepcionante. Pensé que iba a decirme que no puedo proporcionar ambos, pero bueno, ese no es el caso. Pero al menos sé que tengo que proporcionar uno de ellos. Entonces, de esta manera, TypeScript realmente me ayuda a explorar la API y ver qué está disponible y qué tengo que proporcionar o no. Es realmente mucho más claro incluso si lees el tipo, ves que uno de ellos está disponible. O uno de ellos es necesario. uh con respecto a la precisión de los tipos uh puedes ver a menudo una función como esta una función toma alguna cadena que es que tiene que representar algún tipo de acción que quieres tomar por ejemplo en este ejemplo quieres crear un evento de cierto tipo y luego cambias el tipo y proporcionas un tipo diferente de evento para cada tipo. Y luego si recibes un tipo de evento desconocido, simplemente lanzas un error porque ese es un estado inválido para ti, ¿verdad? Y luego como usuario de tal API, voy a decir, bien, voy a llamar a este tipo de evento y tengo que proporcionar una cadena. ¿Qué tipo de cadena? No lo sé. Solo voy a poner ahí alguna cadena. y va a lanzar un error porque esta no es ninguna de estas cadenas que utiliza la función. De nuevo, si el autor de la API en lugar de escribir algo como esto... y ahora, tengo un error. y el typeskip me dice, bien, tienes que proporcionar esto o aquello. Bastante claro.

QnA

Explorando Typeskip y Herramientas de Desarrollo

Short description:

Typeskip ayuda a detectar errores y explorar APIs. Se necesitan entornos de desarrollo integrados y editores capaces de TypeScript. La aplicación tiene un error al crear eventos a partir de los existentes. El tema se ve afectado por la configuración del navegador.

Así es como Typeskip te ayuda a detectar tus errores y explorar las APIs. Realmente deberías pensar en Typeskip como tu cuerpo que está detrás de ti y te dice qué hacer y qué no hacer.

Bien, con eso, si no tienes ninguna pregunta, podemos empezar con la primera tarea que tenemos preparada. Si tienes la aplicación en funcionamiento, de nuevo, como dije, es solo una simple aplicación Next creada con Create Next app. Bueno, el único comando si tienes la aplicación clonada en tu ordenador localmente, solo ejecutas un NPM NPN CI para instalar tus módulos NuN. Y luego NPM run def para iniciar la aplicación en modo de desarrollo. Debería iniciar en el puerto local local host 3000. Quizás podemos darle a la gente un poco de tiempo para clonar realmente el repositorio y ejecutar el proyecto localmente, si alguien necesita el tiempo.

Y hay una pregunta para ti. ¿Cuáles son los entornos de desarrollo integrados u otras herramientas de software necesarias para desarrollar la aplicación del proyecto? ¿Es suficiente si la gente simplemente clona el repositorio y ejecuta MPMI? Bueno, deberías tener algún editor con capacidades para desarrollar un proyecto TypeScript. Esencialmente lo que necesitas hacer es, cuando tienes el editor abierto, entonces ver algunos identificadores y ver el tipo del identificador. vamos a trabajar con muchos tipos, así que es bastante esencial ver los diferentes tipos de tus identificadores. Por ejemplo, en el código VS todo funciona por defecto y no hay que preocuparse. Si tienes cualquier otro editor, solo necesitas que el editor sea capaz de trabajar con TypeScript como servidor de lenguaje. para aquellos que no saben el comando ci es bastante similar al comando de instalación es solo instalar paquetes de acuerdo al paquete log así que vas a tener que tener la misma versión de dependencias que yo lo que hará la depuración mucho más fácil en caso de que haya cualquier problema así que si tienes la aplicación en funcionamiento deberías ver algo como esto aparte de estos dos eventos que añadí hace unos momentos y el primer problema que quería abordar aquí es que puedes crear eventos, puedes crear eventos desde aquí y aquí solo rellenas el nombre del evento y el evento se adjuntará automáticamente al respectivo organizador que tiene el icono adjunto, pero si quieres crear un evento a partir de un evento existente no debería funcionar. Pero lo hace en mi máquina, aparentemente, porque tengo la versión libre de errores en funcionamiento de nuevo.. Vale, esta debería ser la versión con errores. Vamos a intentarlo de nuevo. Y no funciona en absoluto. Voy a limpiar mi almacenamiento local. La aplicación guarda los eventos en el almacenamiento local. Así es donde puedes limpiar todo en caso de que te encuentres con problemas. Pero sí, estoy aquí de nuevo. Y si quiero clonar un evento, ves que ahora no funciona. Ahora el nombre del evento no está rellenado aquí, pero debería estarlo. Así que vamos al código y veamos dónde podría estar el problema. Si abres la estructura, todo lo que nos interesará en esta sesión está en la carpeta Fuente. Hay un viejo código. un par de preguntas sobre las versiones porque el tema parece ser ¿Puedes repetir eso? Sí, ¿me puedes oír? Sí, ahora. Vale, me acercaré. Así que parece que algunas personas incluyéndome a mí están luchando con el tema de la aplicación. ¿Tienes que tener un modo oscuro en el navegador habilitado para ver el mismo tema que tú tienes? tema del navegador tema de la de la aplicación porque estoy viendo un fondo diferente de lo que tienes bien eso es interesante uh el estilo está completamente hecho por el comando create next app okay así que parece que la aplicación el estilo toma tu configuración del navegador en cuenta así que si tu tema en vivo será ligero si tu tema oscuro será oscuro uh no estoy seguro si si funciona correctamente en el tema en vivo no lo probé porque no sabía que tenía tal genial parece tener el mismo comportamiento en firefox y chrome también así que debe ser el tema ligero um hace lo mismo para mí pero la aplicación funciona así que uh si Si lo tienes y lo usas ligeramente, solo, sí, tenemos que lidiar con eso. De lo contrario, parece que funciona. La otra pregunta aquí era si hay otra rama donde hay una versión de trabajo, y si la gente puede cambiar entre la versión libre de errores? Sí. No he hecho el commit de la versión libre de errores todavía. Pensé que iba a hacer el commit al final. Pero si quieres navegar por eso ahora, creo que puedo hacer el commit también en otra rama. Ahora mismo no hay tal rama. Vale, genial. ¿Así que todo el mundo tiene la versión que incluye errores? Sí. Sí. Perfecto. Y la última pregunta aquí era, ¿cuáles son las normas de desarrollo y standards adaptados al proceso de desarrollo del ciclo de vida del proyecto para construir el código y la estructura de data de la aplicación del programa? Creo que esa es una pregunta un poco advanced. Supongo que solo usaste el ejemplo de next JS ¿verdad? Así que supongo que puedes encontrar tu respuesta allí Mohamed. De lo contrario podemos retomarlo al final de la masterclass para que no nos quedemos atascados en

Entendiendo los Type Guards y Sus Ventajas

Short description:

La estructura de la aplicación incluye una carpeta con módulos y tipos TypeScript para entidades. Se utiliza la biblioteca Generic Type Guard para crear type guards y recuperar el tipo de la entidad. Los type guards son funciones que devuelven un booleano en tiempo de ejecución para comprobar si un argumento es de un tipo específico. Los type guards se utilizan comúnmente para los límites del sistema donde los tipos de datos son inciertos. Se utiliza el tipo desconocido para afirmar que una entrada externa es de un cierto tipo. La biblioteca Generic Type Guard proporciona utilidades para construir type guards para tipos de objeto. Se utiliza una utilidad llamada isInterface para crear type guards para propiedades de objeto. La utilidad makeAdditOnly modifica un type guard para devolver un tipo de solo lectura. Declarar tipos en type guards permite flexibilidad para eliminar propiedades de los tipos sin afectar al type guard. El tipo de utilidad de tipo basura es una función de nivel de tipo que transforma el tipo de un type guard. Al aplicar el operador de tipo, la función de nivel de tipo acepta el tipo de un type guard como un valor constante.

ahora mismo. Vale, creo que eso está bien. Podemos continuar. Bien. Entonces, la estructura de la aplicación si vas a echar un vistazo, entonces hay una carpeta con modules que hay algunos TypeScript tipos de algunas entidades con las que trabajamos en la aplicación. Podrías notar que la definición es es un poco extraña. Es porque utilicé una biblioteca llamada Generic Type Guard para crear type guards para la entidad y al mismo tiempo desde el type guard obtener el tipo de la entidad en realidad. No sé si sabes lo que es un type guard. Es solo, es una función que durante el tiempo de escritura, runtime devuelve un booleano, ya sea verdadero o falso. Y para el TypeScript, proporciona la información si el argumento proporcionado es de algún tipo, o no lo es. El tipo debería ser subtipo del tipo proporcionado. Así, por ejemplo, puedo tener un, podemos tener un podemos tener un type guard que recibe un argumento de tipo booleano y voy a decir vale si devuelvo verdadero el argumento es en realidad de tipo verdadero no de tipo booleano sino de tipo verdadero, ves en un en TypeScript en TypeScript, algo puede ser de tipo verdadero y verdadero está bien. Falso me da un error. que booleano en realidad es solo una unión de tipo verdadero o tipo falso, algo así. Así que puedo tener un puedo tener un type guard que dice, vale, veré si un argumento. Y en el tipo devuelto, diré, vale, el argumento es algún tipo más específico de del tipo que he recibido. Y luego la implementación de la función realmente depende del implementador. Puedo simplemente devolver siempre verdadero, que obviamente no es una implementación válida. O puedo decir algo así, que sería una implementación válida. Así que este es un type guard y obviamente el tipo, Así, una de las formas comunes de los type guards es que recibes un desconocido, porque uno de los usos más comunes para los type guards son los límites de tu sistema. Cuando escribes en tu aplicación, tienes algunos límites. Por ejemplo, obtienes algunos data de una API. Los data que recibes de la red son algunos data de los que realmente no puedes estar seguro de qué tipo de data es. La función JSON parse devolverá cualquier cosa, porque es solo una cadena que has analizado y tú no estás seguro de lo que hay en ella. Así que esto es algo de los data proviene de fuera de tus límites, fuera de tu sistema Eso está dentro de tu sistema. Todo está tipado y perfecto y hermoso. Y tú, puedes estar seguro de que lo que recibes es lo que los tipos declaran que debería ser, pero desde fuera de nuestro sistema, no puedes estar seguro de eso. Así que, uh, si recibes de algo fuera de tu sistema, debería ser de tipo desconocido porque el tipo desconocido no es asignable a nada. Es algo que. que primero tienes que usar type guard en para afirmar que es de un cierto tipo. Así que si reescribo mi type guard, será este type guard que acepta desconocido en su lugar. Voy a, funcionará igual, pero debería simplemente reescribir mi implementación a algo como esto. Irko, ¿podrías hacer la fuente un poco más grande? Por supuesto. Gracias. ¿Puedo quitar el… Puedes usar el atajo, puedes hacer clic en la parte superior y luego usar el atajo de comando más. Pero el puntero debería estar lejos de la página en sí. puedes hacer clic en algún lugar fuera de la página sí vale gracias ¿es suficiente principiante o debería vale así que la implementación adecuada para este type guard sería algo así esto correcto porque primero necesitamos afirmar en runtime que realmente es un booleano porque nosotros no sabemos qué va a ser, puede ser un objeto, puede ser un número, puede ser nulo, indefinido, lo que sea. Así que este es un type guard. Y el type guard, guarda el argumento de que será de un cierto tipo y básicamente la biblioteca de tipo guard genérico proporciona un conjunto de type guards y un conjunto de utilidades para construir typeguards por ejemplo aquí hay una utilidad es interfaz que proporciona un typeguard para construir typeguards de un tipo de objeto aquí especificamos typeguards para diferentes propiedades vamos a decir que vale el tipo que vamos a recibir debería ser un objeto objeto debería tener una propiedad id que debería ser de tipo string y debería tener una propiedad nombre que también debería ser del mismo tipo. Y luego vamos a llamar a la función get que simplemente hace, crea el type guard al final. Y al final, hay una pequeña utilidad que escribí que básicamente modifica un type guard para devolver un tipo de solo lectura, porque a menudo me gusta trabajar con tipos de solo lectura y un código inmutable porque, es simplemente más fácil de seguir al menos para mí. Y de nuevo, este make-addit-only, es una utilidad bastante simple que modifica un type guard existente que transforma una entrada en una salida o asails el tipo de entrada es en realidad de tipo de salida y modifica el type guard de tal manera que también, no solo asails que es un tipo de salida, pero también es un tipo de salida de retorno. ¿Y cuál es la ventaja de declarar el tipo de esta manera? Porque si miras el tipo de organizador, es exactamente el tipo que especificamos en el tipo que, pero también podemos, podrías decir por qué no escribimos el tipo directamente y luego escribimos el type guard aparte de esto, nosotros mismos. Bueno, la ventaja de esto es que realmente especificamos lo que el tipo debería tener en el type guard. Y porque TypeScript es un sistema de tipado estructural, si yo escribiera un tipo, por ejemplo, con propiedades ID y nombre. Luego escribo un type guard que afirma tal tipo, y luego, volvería y diría, vale, en realidad no necesito la propiedad nombre por alguna razón porque no me gusta. Simplemente eliminaría la propiedad del tipo en sí. Entonces tendría el type guard al lado de él. No estaría obligado a eliminar la comprobación de la propiedad como en realidad puedo mostrarlo sería más fácil bien y ahora esto es esto es un type guard de mi tipo de organizador y ahora si yo digo vale no quiero esto no hay error el type guard seguirá todavía comprobando que el nombre está ahí y fallará si el nombre está ahí pero no debería no debería fallar pero lo hará porque el typeskit no lo hará hacer cumplir el typeskit no hará cumplir el type guard para comprobar exactamente el tipo puede comprobar algún tipo que eso es más amplio que tiene más propiedades eso no es lo que quiero aquí así que en lo que en lugar de eso hice es que definen el type guard en lugar directamente y luego inferir el tipo del type guard este tipo de basura utilidad tipo es puedes pensar en estos tipos de utilidad como tipo de nivel funciones, aceptan un tipo y luego devuelven un tipo. Así que, básicamente, transforman el tipo. Tienen algunas entradas y algunas salidas y ambas son tipos. Eso se llama función de nivel de tipo. Y esta función de nivel de tipo, acepta un tipo de un type guard, que es este. Y porque este es un valor de nivel runtime, no es un tipo, es una constante, necesitamos aplicar el operador de tipo que obtiene el tipo del valor de runtime.

Explorando Type Guards y Correcciones de Errores

Short description:

Exploramos una utilidad que extrae el tipo protegido. Tenemos modelos, almacenamiento de datos, componentes de interfaz de usuario y un error en el componente creador de eventos. El error se relaciona con una variante de tipo string y una comparación incorrecta. Corregimos el error y encontramos más errores en la lista de eventos. Investigamos las propiedades opcionales y mejoramos las definiciones de tipo.

Y esta utilidad simplemente extrae el tipo que está protegido. Y no tenemos que definirlo manualmente, y luego no hay problema con la tipificación estructural, porque ahora, si elimino la propiedad nombre, ya no está en el type guard también.

De todos modos, Así que esto es solo un pequeño desvío hacia los typeguards. Así que tenemos aquí definidos algunos modelos usando typeguards, como expliqué antes. Luego tenemos data. Aquí es donde almacenamos, en realidad, esas entidades en el almacenamiento local. Hay una llamada al almacenamiento local. Hay una entidad segura, en última instancia, estas eliminan la entidad. Operación estándar de tripulación. tenemos algunos componentes de interfaz de usuario, nada realmente interesante. Y luego en la aplicación podemos ir al creador de eventos y a la lista de eventos. En realidad, el creador de eventos podría ser de interés, porque este es el componente que maneja maneja esto. Tenemos un formulario, tenemos una entrada para el nombre. Tenemos un menú desplegable que es opcional solo para algunas variantes, aparentemente. Que muestra el campo del organizador, este. y tenemos el botón de enviar. ¿Y dónde podría estar el error? Bueno, esta variante, controla si abrimos el creador desde este botón, este botón o este botón. Y la variante es de tipo string. ¿Y qué hacemos con la variante? Bueno, la comparamos si es un evento, la comparamos si es estándar. si es un evento entonces probablemente no sea cualquier string debería ser algún tipo de unión de letras de string como nosotros exportamos antes así que deberíamos estrechar el tipo así oh Sabemos que puede ser una variante estándar o puede ser una variante de evento. Eso es lo que usamos aquí. Vale. Todo parece estar bien aquí. Y ahora tenemos un error en la lista de eventos. Oh. Vale. Y veo el error directamente, puedes ver el error Podemos porque usamos para evento en lugar de En lugar de evento No, uno más aquí en lugar de evento que debería pasar en su lugar así que pasamos eso en el valor inválido y Eso es probablemente lo que causó el error Intentaré corregir eso una vez que averigüe dónde estoy. Vale. Ahora debería estar mejor. Parece ser el problema ahora. Vale. También intenta enviar para organizar para organizador. que es algo que no tenemos en nuestra lista, así que lo añadiremos. ¡Genial! Y ahora no tenemos errores aquí. Probemos la aplicación de nuevo. No, este. vale ahora tenemos un poco más de errores así que probablemente no lo arreglamos realmente así que vamos a profundizar un poco más y tenemos dos propiedades opcionales id del organizador y id del evento fuente Ambos son opcionales. Siempre es un poco sospechoso cuando veo más propiedades opcionales y si vamos, vemos, vale esperamos que si estamos en el evento, queremos que el id del organizador y el id del evento fuente estén especificados. probablemente no queremos poner indefinido aquí, en la clave que se usa para guardar las entidades. Así que este es el primer problema, cuando se usa la variante de evento, ambos deberían ser requeridos, no opcionales y si usas para organizador el id del organizador probablemente debería estar definido también así que definiremos un mejor tipo para esto el tipo probablemente debería ser una unión porque queremos queremos diferentes tipos para las sondas para diferentes variantes así que empezaremos definiendo empezaremos definiendo qué tipos deberíamos esperar para cada de las diferentes variantes y luego vamos a conectar esas variantes en un tipo de unión así que definiremos un mapa porque lo que realmente es es un mapa de un tipo de variante en en un tipo de objeto que debería ser concatenado en las propiedades restantes. Así que definimos algo como perVariantProbs, porque esas son diferentes propiedades que son esperadas para diferentes tipos de variantes. Y diremos, OK, la primera variante es por evento de evento. ¿Verdad? Sí, de evento. Vale. Para el tipo de evento esperamos un objeto con propiedad id del evento, que debería ser de tipo string. Y, id del organizador, que también debería ser de tipo string. Vale. Así que, tenemos más variantes. Y también tenemos el para organizador, correcto. y esto espera también un objeto con propiedad id del organizador.

Explorando el Mapeo de Tipos de Unión y Tipos de Objeto

Short description:

Exploramos el mapeo de tipos de unión y tipos de objeto. Creamos una prueba utilizando la clave de propiedad en la sonda por variante. Transformamos el tipo de unión en una unión de objetos con propiedades relevantes. Aprovechamos los tipos condicionales distributivos para iterar sobre todos los tipos en el tipo de unión. El resultado es una unión de objetos con la propiedad de variante y las propiedades relevantes para cada variante.

Tenemos la variante estándar. La variante estándar realmente no necesita ninguna otra propiedad. Así que podemos decir que espera un objeto vacío. Ahora hemos definido qué otras propiedades esperamos para cada una de las variantes. Pero necesitamos hacer esto, o necesitamos convertir esto en un tipo de unión, que vamos a concatenar en el objeto props, porque las props son un tipo de objeto.

Entonces, lo que podemos hacer es, porque una de las cosas que vamos a explorar en este ejemplo es el mapeo de tipos de unión. Y desglosar un poco los tipos de objeto. Porque lo que podemos hacer, podemos escribir una prueba aquí. Y si usamos la propiedad key of en la sonda peri-variante, sin embargo, esto no me dirá más. Typescript realmente no me está ayudando, solo dice que es un keyof de las sondas de variante, pero ¿qué es realmente el keyof de las sondas por variante? Es una unión de string de evento, para organizador y estándar. La propiedad keyof te da un tipo de unión de todas las claves que están en el especificado que pasas al operador.

Entonces, este es un tipo de unión de las claves defendidas. Lo que queremos transformar este tipo de unión, queremos transformarlo en una unión de objetos que tienen todas estas propiedades para las variantes relevantes y también una propiedad de variante que tiene solo una clave específica disponible en el tipo algo así como okay ¿qué es nuestro resultado qué esperamos esperamos algo como esto uh omitiré la tasa solo claves porque solo es tipo porque es solo confuso. Pero el resultado es algo como esto. Esta es la primera variante. Ahora continuemos con la segunda variante. Finalmente, agreguemos una tabla con los valores de 1, 2 y 3. Este es el resultado que queremos lograr. Si tenemos este tipo, podemos simplemente eliminar estas tres propiedades que realmente no son tan útiles en la API y concatenar, y podemos concatenar el tipo en el tipo de props. Y ahora, una vez que tenemos esto, el tipo de props estrechará el tipo de las propiedades restantes basado en la propiedad de variante que suministraremos. Veremos eso en acción en un momento. Así que intentemos hacer eso porque no queremos codificar esto. Queremos en su lugar usar este tipo de utilidad. podemos aprovechar una propiedad de los tipos condicionales. En la documentation se llama tipos condicionales distributivos. Y la propiedad es que si aplicamos un tipo condicional a un tipo de unión, la condición del tipo condicional se aplica por separado para cada uno de los tipos la unión así que aquí puedes verlo como un ejemplo si tienes un tipo condicional de dos matrices que verifica el tipo si se extiende el tipo de cualquier cosa es todo es siempre va a ser cierto cambia el tipo a ser una matriz de los tipos por lo que es solo una especie de utilidad de dos matrices y si aplicamos esta utilidad en una cadena o número vamos a obtener cadena de matriz o número de matriz no cadena o número de matriz eso es uh eso es la propiedad distributiva uh y eso es la propiedad distributiva uh de los tipos condicionales y podemos aprovechar esto para iterar sobre todos los tipos en la unión tipo y transformarlo de alguna manera.

Entonces podemos decir, okay, tenemos key of de nuestro mapa de variantes. Y vamos a decir que, okay, ¿se extiende a cualquier tipo? Si lo hace, vamos a crear un tipo de objeto podemos hacerlo bien en nombre y okay ¿cuáles van a ser las propiedades una propiedad que queremos es la variante y debería ser de tipo ¿cuál debería ser el tipo correcto podemos usar una palabra clave inferir la palabra clave nos dice o hace el typescape para poner el resultado del del del tipo que que encontró o encontró aquí en el en el variable t por lo que en la variable t deberíamos tener cada uno de los tipos en el tipo de unión por separado por lo que en la primera iteración vamos a tener su el de evento en la segunda iteración va a ser para organizador y luego el estándar por lo que es exactamente lo que queremos para la variante propiedad por lo que podemos asignarlo allí y luego tenemos esta propiedad pero también necesitamos estas propiedades por lo que vamos a convertirlas en el tipo y lo que realmente queremos conectar en el tipo es lo que encontramos bajo la clave. Así que para el evento debería ser este tipo y podemos obtener eso usando esta notación de corchetes. Y dado que es un tipo condicional, es como un operador de bronceado para cada uno de los signos de interrogación, también necesitamos la otra rama. Vamos a decir que es un tipo de siempre porque no esperamos caer nunca en esta rama. Okay ¿cuál parece ser el problema, okay, el problema es que el tipo skid no cree que el tipo T es realmente algunas de las claves del tipo de props perivariant. Así que necesitamos asegurarle que realmente es este tipo. Así que vamos a decir okay. Okay. Vamos a decir typescript, infiere el tipo T de esta expresión y también verifica que es una clave de las props perivariant. ¿Correcto? Y ahora ¿cuál es el resultado? El resultado es una unión de un objeto con la variante en una clave de tipo de props por lo que esto es agradable. Podemos ver un ejemplo donde la propiedad distributiva no se activó porque nuestro tipo es un objeto con una variante que puede ser cualquier clave de las props perivariant y luego se concatena un tipo de unión de todos los valores de las props perivariant. Eso no es realmente lo que queríamos. Y el problema es que aplicamos el tipo condicional en esta expresión pero la propiedad distributiva del tipo condicional solo se aplica cuando aplicamos el condicional tipo en el parámetro de tipo solo sin ninguna expresión alrededor de él. Así que lo que necesitamos hacer en su lugar es hacer esto un poco más complicado y vamos a decir okay infiere el resultado de esta de esta expresión en el en esto en esta variable y luego van a hacer otro otro como una condición o un tipo condicional que está anidado en el tipo condicional anterior y vamos a decir okay si el si el tipo T que inferimos previamente se extiende a cualquier tipo que siempre sea regla no hacemos este tipo condicional para la condición en sí solo hacemos el tipo condicional para obtener la propiedad distributiva del tipo condicional solo solo para iterar sobre el tipo de unión. Vamos a decir si el t se extiende a cualquier realmente, crea este tipo, de lo contrario, de nuevo realmente no nos importa la otra rama. Y ahora obtenemos lo que queríamos. Ahora obtenemos una unión de un tipo. Es un poco difícil de ver. Pero ves que hay hay hay soportes, corchetes aquí, y el tipo es objeto con propiedad variante que es solo el string de evento. Ningún otro string. Y las propiedades que están relacionadas con la variante de evento. Y otro tipo en la unión es una variante cuatro organizador que de nuevo tiene solo las propiedades relevantes para el cuatro organizador variante. Así que esto es en realidad lo mismo que el resultado.

Explicación de Palabras Clave y Tipos Condicionales

Short description:

Podemos renombrar esto y concatenarlo en las props, eliminando la variable de resultado. El uso de 'never' en tipos condicionales elimina ciertos tipos de uniones. El tipo de utilidad 'read-only' se puede utilizar para limpiar los tipos al combinarlos. La palabra clave 'infer' extrae el tipo del lado izquierdo de una expresión. La palabra clave 'extends' representa una condición en tipos condicionales. La expresión 'key of' devuelve una unión de todas las claves en un tipo de objeto. La palabra clave 'info' extrae el tipo del lado izquierdo en una propiedad. La segunda palabra clave 'extends' restringe la condición en la expresión.

Entonces podemos renombrar esto a algo como algo más fácil de leer que test. y concatenar esto en las props en lugar de eso y ahora podemos deshacernos del resultado y especificamos las props de una manera agradable en este mapa transformamos el mapa automáticamente usando este tipo de función a nivel de tipo y luego lo aplicamos en las props

La primera es ¿por qué usamos never como el caso falso en el tipo condicional? ¿Deberíamos usar siempre never cuando usamos infer? Never es algo común porque la cosa con never es, si tienes una unión con algunos tipos y luego el tipo never por ejemplo número o booleano o never typescape eliminará automáticamente estos tipos porque los tipos never son algo que nunca va a suceder como por ejemplo una función que siempre lanza una excepción como nunca retorna nada siempre lanza una excepción esa es una función que retorna never porque eso es algo que nunca va a suceder. Por eso el never es útil en estos tipos de ejemplos porque, por un lado, realmente ilustra algo que nunca va a suceder y, por otro lado, va a ser eliminado de los tipos de unión. Okay espero que, sí, eso sea lo suficientemente claro. ¡Gracias!

Y la otra pregunta es, ¿puedes limpiar el tipo usando read only cuando combinas tipos? Puedes usar los tipos para limpiar el tipo Entonces cuando estás combinando tipos si puedes usar read only No estoy seguro de lo que quieres decir con limpiar el tipo lo que el tipo read only o lo que el tipo de utilidad read only realmente hace es así que uh esto fue cuestionado por Massey y él explicó que está en línea y 74. Okay, estoy 74 solo en lugar de 37 a 81 Okay. Todavía no estoy seguro de lo que significa con el En las props per-variant, ¿no podrías usar read-only y luego usarlo solo en la línea 74. Oh, okay. Ahora entiendo. Sí, sí, por supuesto que puedes hacer eso. Puedes hacerlo así también. Perfecto. Y una última aclaración, tenemos otra pregunta sobre aclaración. Vera está preguntando si puedes repasar toda la expresión y explicar lo que cada palabra clave está haciendo. Entonces, tal vez como un resumen o un repaso de esto para explicar rápidamente lo que cada una de estas palabras clave está haciendo porque hay muchas de ellas. Por supuesto. Tu problema en esta expresión. Sí, especialmente el extenso en una primera situación. Sí, creo que es el que estás mirando. Sí. Sí, obviamente. Entonces, la primera es la expresión key of. Ya pasamos por esto. La expresión key of toma un tipo, un tipo de objeto, y devuelve una unión de todas las claves en el tipo de objeto. Entonces, en este ejemplo va a ser solo una unión de una cadena de evento para organizador y estándar, ¿verdad? La palabra clave extends es una palabra clave del tipo condicional, probablemente esté claro aquí en la documentación oficial donde ves que representa como una condición. Si el tipo a la izquierda de la palabra clave extends es un subtipo del tipo en el lado derecho de la palabra clave extends, entonces el resultado de toda la expresión, puedes pensar en esto como un operador temporal en el estándar JavaScript. Entonces, si esto se mantiene, entonces el resultado de toda la expresión es este tipo. De lo contrario, si este tipo no es un subtipo de este tipo, entonces el resultado de toda la expresión es esta expresión después de la llamada colon, no, algo así. No estoy seguro de cuál era el nombre de este operador. No importa. Entonces esto es esta palabra clave extends. Y luego en el lado derecho de la palabra clave extensor, en lugar de este any, tenemos esta expresión, no, esta expresión, está bien. Y esta expresión tiene bastantes palabras clave, así que vamos a descomponerla. Esta parte es la palabra clave info, como dije. Entonces le dice al typescape, dame el resultado del tipo del lado izquierdo, de este tipo, en la propiedad. Entonces, puede ser anidado. Si digo como, el tipo necesita ser de forma A, como esto. Entonces diré typescript, El tipo en el lado izquierdo del operador extends necesita ser un objeto. El objeto necesita tener una propiedad A y el tipo en la propiedad A, por favor dámelo en el tipo T. Entonces el tipo T contendrá el tipo de la propiedad A dentro de este tipo, como si lo escribiera así. Y si lo escribo así, el typescript me dará todo el tipo al t eso es lo que quiero solo quiero un alias para el para el tipo de la expresión en el lado izquierdo así que eso es eso es la palabra clave infer eso es un poco más complicado diría yo y luego tenemos esta parte como esto esto es básicamente es la misma palabra que este extends eso eso es un poco confuso pero juega un papel diferente aquí aquí el papel de este del segundo extents es uh es restringir la condición como yo yo con este con este extents quiero decir que este tipo necesita satisfacer esta condición necesita ser un subtipo de este tipo de nuevo aquí es confuso porque esos tipos esos tipos son los mismos. Entonces es obviamente cierto, siempre cierto, pero el TypeScript no es capaz de reconocer esto y TypeScript no me permitirá indexar este tipo de objeto con el ttype que acabo de inferir porque no está consciente de que esta expresión es la misma que esta expresión. El TypeScript simplemente no ve esto. Así que necesito ponerlo aquí después de la condición después de la después de la extends es solo algún tipo de condición que quiero poner en el en el tipo de entrada espero que tenga un poco más de sentido sí creo que eso es realmente bueno una nota que agregaría aquí es que para cada uno de de las etapas de la expresión, puedes pasar el cursor sobre el tipo y ver qué tipo de resultados obtienes, ¿verdad? Así que eso es lo que me ayudó mucho con el tipo de magia key of que siempre puedes asignarlo a algo y mirar lo que realmente creó. Espero que esto tenga sentido. Hay una pregunta más. ¿Puedes explicar el propósito de usar la palabra clave infer dentro de la definición de tipo de test? No sé dónde está la definición de tipo de test? Oh, probablemente esto, lo renombré. Era test, creo. Sí.

Explicación de la Palabra Clave Infer y Validación de Tipo

Short description:

La palabra clave infer se utiliza para asignar la variante específica al campo o propiedad de la variante. Desencadena la propiedad distributiva de los tipos condicionales para iterar sobre cada una de las variantes. La expresión ayuda a definir las props por variante de manera cómoda. Se utiliza una afirmación a nivel de tipo para solucionar el problema de concatenar una cadena en las props, asegurando que sea un objeto. El tipo de registro se utiliza para validar el tipo y afirmar la condición de que el valor necesita ser un objeto con cualquier clave de cadena. Estas líneas aseguran valores válidos para las diferentes variantes.

¿Cómo ayuda a definir los tipos para la propiedad de la variante? Parece que te estás quedando atrás, tienes problemas de conexión. Oh, lo siento por eso. ¿Está mejor ahora? Sí, sí. Ahora te puedo oír. OK, OK. Entonces, ¿debería repetir la pregunta? Si puedes, por favor. Sí. Entonces, ¿puedes explicar el propósito de usar la palabra clave infer dentro de la definición de tipo de test? ¿Cómo ayuda a definir los tipos para la propiedad de la variante dentro de las props por variante? Sí. Este tipo infer solo es necesario para, como necesito esto para asignar la variante específica al campo o propiedad de la variante. Y también lo necesito para desencadenar esta propiedad distributiva de los tipos condicionales, como para iterar sobre cada una de las variantes, necesito que el tipo esté solo. Si está dentro de una expresión como aquí, usaré la clave de, como la expresión que uso para el tipo condicional es esta, entonces la propiedad distributiva que itera sobre los diferentes tipos en la unión no funcionará. Necesito que sea así, solo el tipo y luego la extensión. Por eso necesito el infer para poner este tipo en una variable o poner esta expresión en una variable. ¿Y cómo ayuda a definir las props por variante? Bueno, toda esta expresión ayuda a definir las props por variante porque necesito definirlas cómodamente como un mapa aquí y luego transformarlo en el tipo de unión en lugar de escribir el tipo de unión por mí mismo. Luego puedo ir un poco más allá porque ahora nada me obliga a poner un objeto aquí, ¿verdad? Puedo poner solo una cadena. Y entonces eso va a ser un problema porque voy a concatenar una cadena aquí en el resultado. y luego lo voy a concatenar en las props y las props deberían ser un objeto. No puede ser una cadena o un booleano o algo así, pero podemos solucionar eso, dejémoslo así. Podemos solucionar eso con una afirmación a nivel de tipo. Podemos decir, está bien, tenemos un tipo va a ser una función a nivel de tipo. Eso es. Tendremos una función de afirmación. Aceptaré algún tipo, algún tipo P y tenemos otro, otro uso de la palabra clave extends, pero esta, esta vez es similar a este uso. Este extends le dice al TypeScript que hay una, condición en el tipo de entrada de esta función. Dice que este t necesita ser un subtipo en el tipo del lado derecho. Pero el tipo any no es realmente útil porque todo es un subtipo del tipo any. Así que pongamos algo más útil aquí y en realidad necesitamos este tipo porque pensemos en esto lo que realmente necesitamos necesitamos vamos a vamos a pasar este tipo el tipo entero en la función de validación porque queremos que este tipo sea validado y queremos que esto que con este tipo sea un objeto con algunas claves lo que sea que vayamos vamos a no vamos a restringir las claves las claves pueden ser cualquier tipo de cadena cadena pero el valor necesita ser un objeto. Esa es realmente la condición que queremos afirmar aquí. Así que escribamos esto en el requisito, vamos a usar un tipo de registro, el tipo de registro es un tipo de objeto, el primer parámetro del tipo de registro es el tipo de las claves. El La clave puede ser una cadena. Realmente no nos importa la cadena, pero el valor necesita ser también un registro. Los valores del registro pueden ser de nuevo cualquier cadena. Realmente no nos importa. Y el valor de los diferentes campos en el registro interno puede ser de nuevo cualquier cosa. siempre y cuando el valor entero sea un objeto no nos importa lo que está dentro. Puede ser una cadena, puede ser un booleano, puede ser lo que sea. Así que vamos a decir que es desconocido, puede ser cualquier cosa. Y vamos a escribir la cantidad correcta de estos corchetes angulares y luego vamos a decir, está bien, eso es, todo es el tipo T. Mientras el tipo P pase la condición que nosotros, que aplicamos en el, en el tipo de entrada, simplemente vamos a devolver el tipo. Si no lo entendiste, y luego Y luego, si aplicamos el tipo , Si tienes un error, inmediatamente tienes un error porque el tipo de respuesta no satisface la restricción. Eso se aplica. La restricción es este tipo. Esta es la restricción que aplicamos en la entrada. Y este este tipo no satisface la restricción porque la propiedad estándar tiene un incompatible tipo incompatible en sí mismo porque es una cadena y necesitamos que sea un objeto de cadena como valores y desconocido como cadena como claves y desconocido como valores si nosotros ponemos un registro aquí registro vacío ahora todo está bien así que estas dos líneas asegurarán que siempre usaremos valores válidos para las diferentes variantes, y ahora estamos seguros. Y para probar esto, podemos ir a la lista de eventos. Tenemos un error aquí inmediatamente que nos dice que el tipo de evento no es asignable al tipo estándar. Y eso es porque realmente no proporcionamos las otras propiedades aquí. solo proporcionamos la variante pero no proporcionamos el id del organizador o el id del evento fuente así que necesitamos solucionar esto y podemos solucionarlo con una expresión como esta La sonda de la barra lateral contiene las propiedades que se utilizan para la barra lateral. Como puedes ver, el ID del organizador siempre está ahí, pero el ID del evento a veces es nulo, oh ahora voy a porque si quiero crear un evento para un organizador pero no clonar y clonar un evento existente no necesito un id de evento en este en este caso el id del evento será ahora así que vamos a comprobar cuál es el tipo del id del evento si el tipo es la cadena por lo que se proporciona vamos a pasar ID, y el ID del evento de la cortadora de césped. De lo contrario, si el ID del evento no se proporciona a través de la sondas de la barra lateral solo vamos a pasar en el ID y una cosa más que necesitamos hacer es ayudar a TypeScript a entender la relación entre

Corrigiendo Errores y Analizando Cadenas de Entrada

Short description:

Arreglamos un error relacionado con la provisión de la variante del evento fuente y la propiedad. Aprendimos sobre el uso de tipos de unión y su transformación. Nos encontramos con otro error relacionado con un error tipográfico en la clave. Arreglamos el error y discutimos cómo prevenir futuros errores analizando cadenas de entrada y comprobando partes clave. Las cadenas de plantilla son útiles para componer cadenas y crear funciones a nivel de tipo para analizar tipos.

entre la sonda de variante y esas otras sondas que proporcionamos. Para hacer eso vamos a proporcionar la variante aquí vas a decir que esta rama es para el evento de la variante del evento esta rama es antes de la variante del organizador ahora podemos eliminar esto y el tipo de salto es feliz ese salto es feliz y hemos proporcionado las sondas adecuadas para cada una de las variantes el typescript no nos obliga aquí a proporcionar el elemento fuente, pero nos obliga aquí. Si yo fuera a eliminar esta rama, inmediatamente tengo un error aquí porque no proporcioné la variante del evento fuente, propiedad del evento fuente, cuando tengo que proporcionarla. veamos esto ahora funciona ahora arreglamos el error ¿está claro

Parece que no hay preguntas, así que podemos seguir adelante. Así que, hemos arreglado con éxito este error. Entonces, veamos cuáles son las conclusiones clave de esto. Hemos aprendido cómo usar los tipos de unión para capturar la realidad, y ayudarnos o ayudar a la la aplicación a ser más resistente a los errores, y capturar nuestros errores cuando cometemos algunos errores. Aprendimos cómo podemos iterar sobre los tipos de unión y transformarlos en otros tipos de unión. Como si aplicáramos un mapa a un array. Y hemos aprendido que es bastante fácil transformar un tipo en otro tipo, y Jugar un poco con los tipos. Así que podemos pasar a otro error que está presente en la aplicación. Y de nuevo, si tienes alguna pregunta, simplemente lánzalas.

Y bien, veamos otro error. Voy a crear otro evento aquí. y vamos a intentar borrar el evento y no funciona y tengo un error de consola. Y este parece ser el error. Así que veamos hubo un error lanzado porque la función en el almacenamiento es Vale. Data almacenamiento, Ds. Él es. Aquí está la excepción que obtuve. Es esto de nuevo. Y dijo que para una clave organizador / algún ID / lente como algún ID. no encontró un guardia de tipo adecuado. Entonces, veamos. Veamos por qué está presente el error. Tenemos un objeto para diferentes entidades que queremos guardar. La aplicación soporta entidades de organizador y entidades de evento y entidades de asistente. Las diferentes entidades también tienen relaciones entre sí como podemos como puedes ver aquí que la entidad del evento es una sub-entidad de la entidad del organizador. Lo que esto significa efectivamente es que si queremos guardar, si quieres guardar un evento, proporcionaremos algo como esto, id del organizador como esto organizador / id del organizador / evento / id del evento y lo que parece ser el problema aquí es que hemos proporcionado organizador con una s en lugar de eso así que veamos Y efectivamente, hay un problema aquí. Y hay otro problema aquí. Vale. Y hemos arreglado el error. Y eso es agradable que hayamos arreglado el error, pero nos gustaría prevenir futuros errores de este tipo para que nunca vuelvan a suceder porque es realmente fácil estropear la cadena que esperamos en el tipo de entrada correcto no queremos hacer esto en su lugar lo que podemos hacer con typeshift podemos realmente analizar la cadena de entrada de entrada que recibimos y comprobar que cada una de las partes de la clave, como el organizador y el ID y el evento, realmente coinciden con lo que esperamos que sea. Así que, eso es un poco más desafiante, pero podemos hacerlo. Podemos usar una propiedad llamada cadena de plantilla. Con las cadenas de plantilla, no sólo puedes componer cadenas como esta, Digamos, y veamos cuál es el tipo. Y ahora el tipo es una unión de todas las opciones que he proporcionado en la cadena de plantilla. Este es un uso de la característica de cadena de plantilla. También puedo proporcionar otro comodín aquí, por así decirlo. Y el resultado será la combinación de todas las posibilidades que resultan del trabajo que proporcioné. Esto es bastante agradable, quieres proporcionar muchas opciones diferentes por ejemplo si para algunas bibliotecas de componentes y cosas como eso entonces necesitas mezclar un montón de posibles tipos pero veamos otro uso de la propiedad de cadena de plantilla vamos a escribir una función que acepta algún tipo de entrada t que debería ser Debería ser una cadena. Esta función a nivel de tipo sólo acepta cosas. Lo que hará, comprobará el tipo y verá qué, intentará analizar el tipo. Veamos. Algo como esto. Vamos a inferir, Vamos a inferir lo que está después de la parte de entrada de la cadena. Y el resultado, lo vamos a inferir en la variable de tipo res. Y si el tipo de entrada T coincide con esto, vamos a devolver el tipo res. De lo contrario, nunca nos vamos a molestar de nuevo con este tipo. Así que veamos cuál es el resultado para algo como esto. Y el TypeScript analiza correctamente sólo el tipo, sólo la parte de la cadena que realmente nos interesa.

Análisis de Cadenas y Análisis Recursivo

Short description:

Podemos analizar la cadena en diferentes partes basándonos en la clave de entrada. Queremos generalizar el análisis a cualquier clave de nivel superior de una forma especificada. También necesitamos analizar recursivamente las subentidades llamando a la función TypeScript sobre sí misma. Al iterar a través de las claves del objeto de forma, podemos analizar las propiedades deseadas en diferentes niveles.

Entonces, podemos aprovechar esto para analizar esta cadena en las diferentes partes que nos interesan. Entonces, intentemos analizar la cadena. Aceptaremos la clave como entrada y esperamos que la clave sea un subtipo del tipo de cadena. Declaración. Voy a analizar la cadena y espero que esté allí. Organizador aquí, e inferir inferir el resultado. Vamos a devolver el resultado y probemos con la clave de ejemplo. y obtuvimos correctamente todo lo que está después de la parte del organizador de la clave.

Bueno, pero esto es algo específico, y en realidad nos gustaría analizar cualquier cosa que esté especificada en este tipo de objeto. No queremos que esto sea específico para el organizador, luego otro para el evento, evento, y luego otro específico para el asistente, ¿verdad? Intentemos generalizar esto un poco. Y digamos que queremos analizar... Queremos que esta parte sea cualquier clave de nivel superior de esta forma. Entonces digamos keyof typeof... Annapurv.dummy... Y luego esperamos una barra e inferimos el resultado y de nuevo devolvemos el resultado No debería haber eliminado eso esto aquí, tienes el resultado que se analizó correctamente y para otra prueba Probemos una clave diferente. Es otra clave válida que esperamos. Hay un attendD slash ID. Y esto también se analiza correctamente. Pero ahora sólo funciona para las propiedades de nivel superior y también nos gustaría analizar la parte del evento de la propiedad. porque aquí no tenemos el id del evento, sólo tenemos el organizador slash evento slash id que no es realmente lo que queríamos, así que para hacer esto necesitamos iterar más profundamente, necesitamos recursivamente pasar por las subentidades y analizar lo que está dentro y esto es realmente algo que podemos hacer con typescript podemos llamar recursivamente a la función typescript sobre sí misma Y también necesitamos cambiar el objeto que comprobamos para las claves porque en el nivel superior, comprobamos estas claves. En el siguiente nivel, comprobaremos esta clave y cualquier clave que añadamos más tarde. Así que recibiremos el objeto como argumento. Va a ser, llamemos a esto forma, formas. Y debería ser un registro de claves de cadena, no, no esto, claves de cadena. ¿Y cuál debería ser el valor? Bueno, el valor también debería ser un registro, o más bien un objeto con un tipo de guardia. digamos, no nos preocupemos por esto ahora y las subentidades No importa realmente, ¿verdad?, no importa también entonces, formateemos esto para hacer esto un poco más legible Muy bien. Y ahora, en lugar de esto, en lugar de codificar el objeto, vamos a usar el parámetro que hemos comprado aquí. Vale. Y no sabemos que el TypeScript no está realmente seguro de que las claves de los tipos de formas sean de tipo cadena. Así que vamos a intentarlo de nuevo. Vale. Eso es raro. Eso es raro, Vale, ¿cuál parece ser el problema? Hmm, realmente piensa que puede haber Algo más es en cadenas. Aunque sólo debería haber cadenas. Interesante. Vale, intentemos solucionar esto. Intentemos hacerlo así. Vamos a guardar las claves dentro de otra variable de tipo. Digamos claves. Y vamos a decir que las claves deben ser de tipo cadena. Ahora que tenemos las claves guardadas dentro de la variable que está asegurada para ser de tipo cadena, debería ser posible usarla. Así que continuemos con la clave. Debería ser extensión de clave barra un mensaje asignado. Tomaremos el resultado, verificaremos el resultado, de lo contrario no nos importa realmente. Ahora funciona. y ahora necesitamos proporcionar otro argumento aquí, así que el argumento realmente es lo que usamos antes porque eso es lo que queremos usar la especificación del tipo y obtuvimos nunca eso es interesante no funciona realmente aquí, vale, dividamos esto, veamos veamos cuál es el problema, vale, el problema es esta parte que el script no es capaz de porque usé clave en lugar de claves, ¿verdad? Vale, ahora funciona. Y obtuvimos el mismo resultado que antes. Incluso podemos tener otra prueba para la clave del organizador para asegurarnos de que funciona para todas las combinaciones que actualmente soportamos, y lo hace. Pero cuando obtenemos la clave de nivel superior, no queremos terminar aquí, queremos continuar recursivamente a las subentidades. Así que, intentemos esto.

Análisis Recursivo de Claves e Inferencia de Tipos

Short description:

Necesitamos detener la recursión cuando llegamos a la clave final. Solo nos importa la parte actual de la clave. Las subentidades deben ser de tipo registro. Necesitamos comprobar que las subentidades satisfacen la forma deseada. Podemos usar otro nivel de tipos condicionales para lograr esto. Queremos inferir el tipo de la clave que encontramos y comprobar las sub-entidades para esa clave específica.

Con cada recursión, también necesitamos detenernos en algún lugar. No queremos recursar infinitamente. Así que la condición de parada es cuando no queda nada más. Solo la clave final y nada más. Porque por ejemplo aquí, solo tienes la condición de nivel. Aquí, vamos un nivel más profundo, y luego no queda nada más. Y también avanzamos dos segmentos. Básicamente, comemos una barra cada vez que vamos más profundo. Así que intentemos codificar esto en el código y digamos que si tenemos algo como esto si tenemos una clave de nivel superior entonces alguna cadena que es el ID realmente no nos importa hay alguna cadena detrás de la barra entonces tienes otra barra y algo algo más, lo que sea que sea eso es algo en lo que necesitamos continuar eso es el resto de la clave esta parte de la clave ya no es de interés realmente no nos importa esta parte ahora solo nos importa esta parte así que continuaremos analizando esta parte de la clave ponemos el resto aquí desde las formas correctas nosotros Necesitamos seleccionar las subentidades. Parece que podemos hacer eso porque las subentidades son de tipo desconocido. Eso no es realmente lo que queríamos. Así que vamos a decir que las subentidades son un registro. ¿Es mejor? No, no lo es. Tendremos que ajustar eso. Tendremos que comprobar que las subentidades Oh, y no puedo detectar correctamente. Necesitamos comprobar que las subentidades de nuevo satisfacen este tipo de forma. Podemos hacer eso con otro nivel de tipos condicionales. Básicamente, siempre que tengas un problema con los tipos condicionales casi siempre lo solucionas con otro nivel de tipos condicionales. Así que digamos formas. Veamos cuál es el... Vale. Hay una cosa más. Queremos inferir cuál es el tipo de la clave que encontramos. Porque el primer segmento puede ser cualquiera de las claves de nivel superior. las claves de nivel superior y queremos comprobar las sub-entidades para la clave específica que encontramos aquí. No todas ellas. Así que de nuevo, necesitamos inferir esto. Nombrémoslo correctamente. Y decimos que queremos inferir la entidad que encontramos. La entidad debería ser algo de las claves, del nivel superior, de las formas que recibimos.

Análisis Recursivo de Claves y Validación de Entidades

Short description:

Verificamos si la subentidad es un registro con la misma forma que la llamada recursiva. Si es así, recursamos con el resto de la clave. Manejamos el caso cuando no hay nada más en la clave. Devolvemos la entidad que encontramos o manejamos el caso cuando ninguna condición se cumple. Todo parece estar funcionando.

Bien. No hay uno y sésamo, y ahora en lugar de cursar inmediatamente vamos a comprobar que shapes es en dansing. sub entidad realmente es un registro que tiene cadenas como claves y básicamente la misma forma que que queremos proporcionar para la llamada recursiva. Si lo hace, entonces necesitamos recursar. Y queremos recursar con el resto de la clave. Y bien, necesitamos inferir el resultado de nuevo. de nuevo, next, esos son los siguientes shapes que queremos proporcionar. Cerramos los siguientes shapes aquí. Y de lo contrario, de nuevo, realmente no nos molesta con el segundo, porque esto siempre debería ser cierto. Si no es cierto, hay algo mal con esta estructura de data. Bien. Siempre terminamos en el caso de never. Eso es porque realmente necesitamos preocuparnos por el otro caso. Y necesitamos preocuparnos por el otro caso para esta condición porque esta condición espera que siempre haya algo más. Pero eso no siempre es cierto. A veces estamos al final de la clave y necesitamos terminar con algo. Y si queremos introducir algo, necesitamos usar la otra condición. Así que si estamos al final, la clave debería extender una forma diferente. Debería extender algo como esto, por favor. Y luego algún ID y luego no hay nada más. Esta es la última entidad que encontramos. Esto es cierto. Podemos devolver la entidad que encontramos, por ejemplo, y de lo contrario, este es el caso de que ni esto ni esto coincidan. Esto realmente debería estar ahí. Y hemos pasado el evento desde aquí. Esta es la última entidad que encontramos. Tenemos organizador porque esta es la última entidad y todo parece estar funcionando.

Análisis de la Clave y Verificación del Tipo

Short description:

Analizamos con éxito la última entidad y verificamos la validez de la clave y el tipo deseado. La cadena en sí no es importante; queremos analizar Shapes y seleccionar el Guard. El Guard asegura que la entidad recibida coincide con la clave proporcionada. Podemos renombrar esto a 'clave para guard' y obtener el tipo de entidad protegida.

Entonces, ya que hemos analizado con éxito la última entidad que encontramos, debería ser bastante fácil verificar que la clave es válida y comprobar qué tipo de tipo realmente queremos. Porque esto es realmente a lo que apuntamos con todo el análisis de la clave. El análisis parecía innecesario, pero es necesario para verificar que si quiero guardar entidad con esta clave necesito proporcionar el tipo que es analizado por este typeGuard que significa un tipo de evento por lo que realmente queremos analizar aquí no es no la cadena la cadena no es realmente interesante en sí misma sino realmente Queremos algo como Shapes, donde indexamos esto con la entidad encontrada. Esto debería ser este objeto o este objeto dependiendo de lo que analizamos. Y queremos el Guard. Entonces, simplemente seleccionaremos esto. Y ahora lo que obtenemos es el guard que verifica que la entidad que recibimos es del tipo que coincide con la clave que proporcionamos. Esta información podemos renombrarla a algo más útil. Veamos, ¿hay un símbolo de renombrar? Lo hay. Así que es algo como clave para guard. E incluso podemos obtener el tipo adecuado. porque esto podría ser más útil que obtener el guardia en sí, podría ser obtener la entidad protegida, que será más útil en un momento. Entonces, aquí podemos reutilizar esto. Y podemos usar, podemos usar la biblioteca para obtener el tipo descartado por el corte. Y si usamos esto aquí, esto un poco, tenemos el dado que tenemos, tenemos el tipo que está asociado con la clave especificada.

Inferir las Siguientes Formas y Mejorar los Mensajes de Error

Short description:

Inferimos las siguientes formas para la entidad dada basándonos en el objeto de nivel superior asociado con la clave recibida. La entidad puede ser un evento, organizador o asistente. TypeScript no permite sobrescribir la entidad original con un tipo inferido. Hacemos la función genérica para trabajar con diferentes tipos de claves y transformamos la clave en el tipo de entidad asociado. El tipo de la entidad debe coincidir con la clave proporcionada. Podemos mejorar los mensajes de error devolviendo un literal de cadena con el mensaje de error deseado en lugar del tipo 'never'.

Yurko, una pregunta rápida. ¿De dónde vienen las siguientes formas? Las siguientes formas. Las siguientes formas son las que inferimos para la entidad dada. Como cuando vamos, tenemos las formas, este es el objeto de nivel superior o el objeto que está asociado con la clave que recibimos, e inferimos la entidad que está en el nivel dado de la clave. Es evento, organizador o asistente. Esa es la base. Y obtenemos del objeto, obtenemos el objeto que está asociado con la entidad, obtenemos las subentidades, y esas son las siguientes formas. Lo inferimos. Sí, creo que esa era la pregunta. Creo que simplemente nos perdimos la línea 81. Eso debería estar bien.

Y una pregunta, un poco más antigua, así que creo que ya cambiaste el código, pero se trata de inferir las variables, y la pregunta es por qué tuvimos que darle a la variable inferida otro nombre? Sí, porque Typescript básicamente no nos permite la entidad original o el tipo original con otro tipo que acabamos de inferir. Siempre tiene que ser un tiempo diferente. No está permitido sobrescribirlo entonces. Gracias por eso. Creo que puedes continuar. Gracias por las preguntas.

Así que ahora tenemos la capacidad de ir de la clave al tipo de entidad. Y eso nos ayudará a salvaguardar esto. Por ejemplo aquí, tenemos una función que acepta la clave que puede ser cualquier tipo de cadena y una entidad que queremos guardar asociada con la clave que proporcionamos. Y de nuevo, realmente no hay type safety aquí. Podemos proporcionar cualquier tipo de entidad, podemos proporcionar cualquier tipo de clave de cadena Así que vamos a mejorar esto con nuestros tipos. Vamos a hacer de esta función una función genérica porque necesitamos que la función funcione con diferentes tipos de claves, pero necesitamos trabajar con el tipo de la clave. Así que necesitamos asignarle algún nombre. Ahí es donde ayudan las funciones genéricas. Así que vamos a decir que. queremos una propiedad de clave o una variable de clave y el parámetro de clave ahora no es cualquier cadena sino es una cadena de tipo clave y vamos a aprovechar esto para transformar la clave en un tipo de entidad asociado. Y ahora el tipo de la entidad debe coincidir con la clave proporcionada. Podemos probar esto rápidamente. Digamos que queremos decir usando el organizador con un ID muy extraño. Ahora TypeScape ya me dice que necesito proporcionar ID y nombre que es el tipo de el objeto organizador. los valores reales no son realmente interesantes en este momento y aquí si pasamos el cursor sobre el uso de una función genérica podemos ver los parámetros que typescape inferió para nosotros y podemos ver de hecho que los tipos son correctos si fuéramos a proporcionar si tú si tú hicieras el mismo error de tipeo que hicimos antes eso es lo que causó el error antes vamos a obtener un error inmediatamente porque el tipo que usamos, el tipo de entidad clave, no pudo pasar esta condición porque el primer segmento no es una clave de las claves de las formas. Las formas son estas formas de aquí y las formas de nivel superior sólo tienen estas claves. asistente y organizador. Y aquí, gracias a nuestro error de tipeo, esta parte no es tal clave. Así que va a terminar en un caso nunca. Para mejorar los mensajes de error, porque typeskip sólo nos dice que el tipo no es asignable al tipo nunca y desde la perspectiva del usuario no estoy realmente seguro De lo contrario, nunca están escribiendo. ¿Qué significa eso? Así que podemos mejorar esto. Para mejorar esto, necesitamos encontrar el caso adecuado donde asignar esto. Y el caso adecuado está aquí. Porque vamos a pasar la primera condición, la segunda condición. Y este es el caso falso de ambas condiciones. Y podemos, en lugar de nunca, podemos devolver un literal de cadena y el literal de cadena contendrá el mensaje de error que queremos pasar al usuario. Así que algo como... ...Encontré. Y si vamos al mensaje de error ahora, supongo que no es la rama adecuada después de todo. Así que vamos a ver. Ponlo aquí. Pero esto no debería ser la página adecuada. no realmente esta cara bueno hay algo algo que me estoy perdiendo tú Oh, hay un error aquí.

Corrigiendo la Condición de Entrada y Cargando Entidades

Short description:

Corregimos la condición de entrada del tipo protegido añadiendo otro nivel de tipo condicional. Los mensajes de error proporcionan explicaciones elaboradas por nosotros. Podemos usar cadenas de plantilla para proporcionar mensajes de error específicos. El sistema de tipos de TypeScript analiza la cadena proporcionada e infiere el tipo adecuado basándose en las diferentes partes de la clave. El mismo tipo puede ser utilizado para cargar entidades, proporcionando resultados correctamente tipados basados en la cadena proporcionada. El código puede ser extendido para cargar múltiples entidades ajustando los parámetros de la función a nivel de tipo.

Vale. Sí. Movamos esto, movamos esto dentro por ahora, porque sabemos, no cumplimos con, no cumplimos con la condición de entrada del tipo protegido, porque no pasamos algo Que puede ser un tipo parcial de guardia. A veces pasamos una cadena que no es realmente lo que se trata aquí. Así que si esto lo averiguaremos más tarde. vale y de nuevo no cumplimos con la condición así que vamos a arreglar esto con otro nivel de tipo condicional Ves los niveles de comunicación, diferentes literales. Actualicémoslo. Vale, no, no hay errores aquí. Y tenemos el mensaje de error aquí. Ahora, TypeScript se quejará de que el objeto que proporcionamos no es asignable a algún tipo de cadena, lo cual es extraño. Pero la cadena en sí misma contiene algún tipo de explicación que proporcionamos como implementadores del tipo. Podemos usarlo como una especie de truco, pero puede ser usado para crear mejores mensajes. Incluso podemos usar. Me pregunto qué caso es porque realmente creo retrocedamos un poco y encontremos la rama correcta. Sí, es la rama correcta. El problema estaba con la condición de entrada. OK. E incluso podemos usar cadenas de plantilla aquí y proporcionar el error que encontramos. Veamos. Y esa es la entidad encontrada. Lo es. TypeScript se queja de que no puede encontrarlo. Eso es interesante. Mhm. ¿Porque estamos en la condición falsa, verdad? Sí, no fue capaz de analizar eso. Vale, entonces añadamos otra capa. sea cual sea el problema es que no vamos a obtener esa información porque esperamos inmediatamente que sea de tipo keys y de hecho si si hay un problema no es del tipo keys es Hay algo mal, ¿verdad? Así que vamos a inferir que sea lo que sea. Y el resultado es de nuevo, no realmente interesante. Supongo, vale. Y en este caso, este caso significa que no es realmente de esta forma que la barra está faltando. Así que ya no nos importa realmente. Sólo vamos a decir que la clave es realmente inválida y no podemos decir qué parte de ella es inválida. este tipo y ahora ahora va a decir que la entidad organizador no es un nombre válido así que sabemos precisamente qué parte es inválida. Oh, esto también es inválido, obviamente. y si añadimos otro problema y ahora se va a quejar de que esto no es asignable al tipo de evento porque el evento tipo tiene muchas más propiedades que realmente no quiero escribir aquí pero podemos usar podemos usar algo de aquí porque este es un evento válido peguémoslo aquí cualquier id y ahora este es un evento válido y ahora realmente lo que hace typescript que es realmente increíble para un sistema de tipos es analiza la misma que proporcionamos y obtiene un tipo adecuado basado en las diferentes partes de la cadena de la clave. Incluso puedes cometer un error aquí y entonces te dirá vale la propiedad awet no es un nombre válido. Así que incluso los mensajes de error son de alguna manera útiles en realidad. ¿Hay alguna pregunta sobre esto? Así que todo está claro. Y podemos usar el mismo tipo para cargar la entidad también. Es sólo cuestión de escribirlo. una entidad, en lugar de aceptar otro tipo vamos a devolverlo, así. Y ahora si fuéramos a cargar una entidad, y fuéramos a proporcionar una tener un resultado correctamente tipado sólo basado en la cadena que proporcionamos. Así que esto es otra parte también puede ser extendida para cargar y múltiple entidades pero necesitaríamos porque con múltiples entidades proporcionamos diferentes tipos de claves proporcionamos claves como esta donde no no proporcionaríamos la id final. Así que, necesitaríamos ajustar el código porque en este código esperamos que siempre haya una id al final. Necesitaríamos proporcionar otro atributo o otra entrada a la función a nivel de tipo que escribimos. Algo como que sería de tipo booleano. En realidad esta es una buena analogía. Puedes pensar en la parte de extensión de los parámetros a nivel de tipo como definiciones de tipo para los parámetros de la función a nivel de tipo. Porque como esta es una función a nivel de tipo, estos son entradas a las funciones a nivel de tipo y estos son tipos para la entrada de la función a nivel de tipo algo como esto vale y necesitamos propagar la bandera que recibimos en las llamadas recursivas y aquí en la parte final de la coincidencia donde coincidimos con el segmento final de la clave vamos a ajustar esto para esperar sólo la ID si esta bandera está establecida en verdadero, algo como oh eso no es lo que pretendía algo como barra y una cadena aquí cualquier id y de lo contrario una cadena vacía porque si si si esto está establecido en falso significa que no esperamos la id final puede ser una cadena vacía así que esto empieza a ser un poco difícil de analizar pero si desglosas la la expresión realmente tiene sentido y ahora digamos a la clave al tipo de entidad también deberías aceptar el parámetro Ahora, si decimos en nuestras pruebas, por ejemplo, necesitamos esto. Y ahora este es el mismo resultado que antes, porque antes esperaba la ID final, y dijimos verdad.

Corrigiendo el Último Error y Conclusiones Clave

Short description:

Arreglamos el último error en nuestra aplicación. Las conclusiones de esta parte son: podemos pasar tipos literales de cadena en TypeScript, iterar en TypeScript usando recursión, iterar en tipos de unión y afirmar valores a nivel local. TypeScript no puede afirmar invarianzas complicadas en la parte de tiempo de ejecución del código.

Y aquí debería haber un problema. eso es interesante, vamos a eliminar esto vale entonces, ¿cuál parece ser el problema? lo pasamos alrededor lo pasamos a la llamada recursiva vale Y en la comprobación extendemos. No es interesante, OK, porque lo puse en el lugar equivocado, sí. Debería estar aquí en su lugar. Esta condición está ahí sólo para extraer el. El. el nombre de la entidad para el mensaje de error. No es útil. No es útil para la lógica real del tipo. Y ahora funciona. También funciona, y si pongo verdadero aquí, tengo un error de clave inválida encontrada, Porque si dije verdadero espero la ID final pero no obtengo la ID final. Ese es el problema. Así que con este tipo voy a arreglar rápidamente estos. Esperar la ID final en esta parte. También esperar la ID final aquí. Pero para cargar entidades, la ID final no debería estar presente. Escribir esto. ¿Cómo se llama? Algo así. Algo así y aquí pasamos pausa porque para las entidades de carga para múltiples entidades la id final no debería estar presente. Vamos a comprobar rápidamente que funciona y de hecho funciona. Devuelve un array de organizadores y si yo pasara una id es un error si yo fuera a obtener eventos de un cierto organizador obtendría una lista de eventos de tipos de eventos vale, tenemos esto funcionando uh bien, esto es fácil Y con esto, el guardar, guardar y cargar entidades, la API de almacenamiento, como quiera que llamemos a esto, es bastante, bastante buena. Y bien tipada.

¿Alguna pregunta más? Sólo hay una pregunta, Mirko. Una pregunta pero un comentario que dice, eso es de Natasha. Que es para tantas condiciones, es difícil de leer. Pero supongo que es cosa de experiencia, puedes leerlo bien, ¿verdad? sí, es sólo que todos nosotros, bueno, es difícil de leer, te acostumbrarás a ello una vez que juegues un poco con los tiempos con los tipos como dijiste es un poco de una cosa de experiencia, pero al mismo tiempo sí, es una parte triste TypeScript como lenguaje es algo de expresivo con este juego a nivel de tipo y funcionalidad a nivel de tipo por lo que puedes hacer muchas cosas pero no es realmente fácil y la sintaxis no ayuda mucho como no puedes hacerlo más bonito con las herramientas que typescape tiene disponibles desafortunadamente genial genial sí creo que de lo contrario no tenemos ninguna pregunta aquí así que espero que sea todo claro como yo dije es es difícil de leer pero no hay realmente otra forma y una vez que te acostumbras a ello así que podría analizar todas las diferentes ramas de las de las condicionales te acostumbrarás te acostumbrarás Así que, arreglamos el último error en nuestra aplicación. Comprobamos antes que funciona. Así que, ahora puedo borrar todos mis eventos y entonces, ¿cuáles serían las conclusiones de la parte final es que podemos pasar tipos literales de cadena en TypeScript. Podemos hacer todo tipo de cosas con literales de cadena y puedes aprovechar esta información para hacer lo que necesites en tus aplicaciones. Es realmente útil. Podemos iterar en TypeScript como lo harías en tu código estándar de JavaScript en tiempo de ejecución, sólo que no tienes ciclo while y ciclos for y lo que sea, sólo tienes recursión. Sólo iteras a través de las recursiones e iteras en tipos de unión. Ese es un tipo especial de iteración. Y sí, no entramos en esta parte. Pero el problema aquí es que si por ejemplo aquí está bien pero si descomento esta parte entonces debería dar un error sí aquí tengo un error porque aquí está bien esto no lo hicimos realmente arreglar esta clave esta esta función esto debería realmente también trabajar para una clave y y más tarde, devolver el guardia de tipo que está asociado con la clave. Y sí, también debería aceptar el, parámetro booleano. Y esto va a ser un problema porque es realmente difícil conectar la parte de tiempo de ejecución, el JavaScript, a estos tipos de nivel de tipo recursivo complicado. Así que normalmente lo que haces, simplemente lo sobrescribes. Aquí, todavía es posible, puedes hacer algo como esto. Pero pero aquí TypeScript todavía no está seguro cuál es el resultado. ¿Cuál es el tipo del resultado? Así que todavía tendría que sobrescribirlo. Así. Sí, y esto no coincide realmente porque no siempre es un guardia. Sí, tendríamos que ajustar eso, pero no vamos a gastar más tiempo en esto. El verdadero problema es que necesitas afirmar esto, en lugar de que TypeScript sepa que coincide porque TypeScript no es capaz de afirmar estas invarianzas complicadas en la parte de tiempo de ejecución de tu código. Así que esto debería ser una de las conclusiones también. Pero la cosa es que haces esta afirmación de valor, como decirle a TypeScript lo que realmente es, y básicamente no escuchar su consejo. Pero haces esto a nivel local, en una pequeña función donde sabes cuál es el resultado. Pero gracias al tipo complicado que escribiste, proporcionas una bonita API para el usuario de la función. la función podría ser usada en muchos lugares diferentes en todo tu código base y todos los lugares serán más seguros gracias a los tipos por lo que esto es un pequeño pero creo que beneficioso título y otra cosa que podrías saber que tampoco entramos en porque me olvidé de eso es la palabra clave satisfacer aquí tenemos el mismo problema que tuvimos en el donde estaba el creador en las propiedades perivariantes en las propiedades perivariantes usamos el tipo de activo para comprobar que no incluimos ningún tipo malo aquí que no queremos aquí pero aquí no tenemos ninguna comprobación de este tipo podemos

Comentarios Finales y Preguntas y Respuestas

Short description:

Tenemos una tarea extra relacionada con las operaciones a nivel de tipo. Contacta a Jirka en GitHub o únete a nuestro servidor de Discord para obtener más ayuda. Jirka generalmente busca respuestas en Google y experimenta para encontrar soluciones. Habrá una grabación disponible y proporcionaremos un correo electrónico de seguimiento con más información. Si asistes a la masterclass de React en Nueva York, visita nuestro stand. Se compartirá el enlace de la grabación y del repositorio de GitHub.

puedo escribir aquí cualquier cosa que no tenga sentido y no tengo un error aquí. Bueno, tendré errores probablemente en otro lugar, pero no los tengo aquí. Aquí tengo un error, pero no tengo un error aquí. En cambio, lo que puedo hacer es decir que este objeto puede ser realmente cualquier objeto siempre y cuando cumpla con el tipo que proporciono aquí. y el tipo debería ser un tipo de registro de cadena tiene un valor en el sentido de que es realmente un guardia de tipo que guarda cualquier cosa, no me importa lo que guarde las subentidades de nuevo. Sí. Y y otro método. Y ahora si escribo algo que no tiene sentido, sentido que él me lo dirá. Justo aquí. Así que eso es donde la palabra clave satisface podría ser útil útil. Vale. Y esto es todo lo que preparé todas las tareas. Tengo una tarea extra para donde no podemos hacer operaciones a nivel de tipo de número como suma y multiplicación pero no estoy seguro de qué es creo que estamos un poco tarde para hacer eso ¿qué te parece si podemos añadirlo a el repositorio de github así que si alguien está interesado en hacer la cosa extra o aprender más siempre pueden ver el código así que en el repositorio habrá tres ramas con la solución de la tarea extra también. Creo que sería bueno. Sí, definitivamente sube eso al repositorio.

Vale, sí. Y creo que estaba diciendo que si alguien tiene alguna pregunta, esta es la oportunidad única de preguntarle algo a Jirka, pero él es un gurú de TypeScript en nuestra empresa. Así que no dudes en preguntar. Por otro lado, Jirka, ¿tienes algo más en la presentación, tal vez una forma de ponerte en contacto contigo si alguien está interesado.

Claro, puedes contactarme en GitHub. No sé si eso es posible. No incluí mi Twitter. Sí, puedes contactarme en algún lugar. No estoy seguro. Y también, también como empresa tenemos un servidor de Discord. Así que si vas a nuestro sitio web, tal vez puedes mostrarlo en el sitio web donde la gente puede encontrar el enlace. Si vas a nuestra página principal de content.ai, siempre hay un enlace a Discord en el pie de página. Así que, si te unes al servidor de Discord, Irkan, otros chicos de DevRel siempre están allí mirando los mensajes. Así que, puedes ponerte en contacto a través de esa plataforma también.

Hay una pregunta sobre un grupo o canal de TypeScript. ¿Sabes si hay algún lugar donde la gente pueda obtener ayuda? Sé que hay un servidor de Discord de Next.js. Pero cada vez que intenté obtener ayuda allí, tuve muy mala suerte porque las preguntas desaparecen muy rápidamente. ¿Cuál es tu experiencia? ¿Dónde encuentras respuestas a los problemas de TypeScript, Jirko? Normalmente solo los busco en Google. Y, bueno, si no puedo encontrar una respuesta con Google, simplemente juego con cosas hasta que encuentro la respuesta usando, como, experimentación. No contacté con ninguna comunidad hasta ahora. Intenté usar chat GPT. A veces puede darte una respuesta utilizable. No siempre es 100% correcto. Así que si usas chat GPT, solo verifica doblemente la respuesta que te dio. Pero puede ser útil para darte algunos saltos en tu búsqueda. Perfecto.

Así que solo una última información para todos los asistentes. Habrá una grabación disponible. Habrá un correo electrónico de seguimiento donde les daremos a todos la oportunidad de ponerse en contacto con nosotros también. Así que, si tenemos... o si el equipo de GoodNation tiene tus detalles, te enviaremos un correo electrónico con toda la información. Así que, cuando Erika lo prepare, estará disponible para ti. Por otro lado, si estás asistiendo a la masterclass de React la próxima semana en Nueva York... Pasa por nuestro stand. Yo estaré... solo vuelve... Vale, creo que mi principal colección roja es esa de nuevo así que tú si puedes terminar. Y sí. Así que, lo que Andre quería decir es que si estás visitando la cumbre en la en la en Nueva York, puedes visitar nuestro stand y yo no estaré allí pero en el evento estado estará allí en persona así que puedes hablar con él, tomar una cerveza algo. y, no sé, eso es probablemente todo. Y la grabación estará disponible, no olvides la grabación. Y también proporcionaremos el enlace, y puedes visitar el repositorio de GitHub. Subiré la versión final allí junto con la edición del título para que puedas ver eso en acción. Gracias a todos, adiós. Gracias, adiós.