Las mentiras que nos contamos usando TypeScript

Rate this content
Bookmark

¿Qué tan segura es la seguridad de tipo de TypeScript? ¿Cuánto puedes confiar en tu código tipado estáticamente? ¿Incluso puedes considerar el sistema de tipos de TypeScript "fuerte"? En esta charla, observamos situaciones en las que TypeScript falla terriblemente y aprendemos por qué las cosas tienen que ser así. Hablamos de compromisos, soluciones alternativas y, finalmente, soluciones para todas las malditas y terribles mentiras que nos contamos a nosotros mismos cuando usamos TypeScript.

 Stefan Baumgartner
Stefan Baumgartner
28 min
21 Sep, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

La charla discute las limitaciones de TypeScript y las mentiras que nos contamos a nosotros mismos sobre su seguridad de tipo. Explora ejemplos de operaciones inseguras y la manipulación del sistema de tipos utilizando palabras clave como afirmación de tipo y función es dado. La charla también cubre la captura de errores de sintaxis, incompatibilidades de tipo y la complejidad de los tipos condicionales y genéricos. Enfatiza la importancia de entender las limitaciones de TypeScript y tomar decisiones bien informadas como ingenieros de software.

Available in English

1. Introducción a TypeScript y sus limitaciones

Short description:

Bienvenidos a mi charla, Las mentiras que nos contamos usando TypeScript. Ha sido un fantástico congreso de TypeScript hasta ahora. Hoy, hablo sobre un ejemplo con el que TypeScript está totalmente de acuerdo. Simplemente estamos obteniendo algunos datos de una API y concatenándolos con algo más. TypeScript dice que es un buen código, pero es muy probable que se bloquee en tiempo de ejecución. Vamos a repasar el código paso a paso.

Hola, bienvenidos a mi charla, Las mentiras que nos contamos usando TypeScript. Ha sido un fantástico congreso de TypeScript hasta ahora. Han visto a muchos oradores fantásticos, personas que quería conocer desde hace mucho tiempo, personas con las que he interactuado en las redes sociales y que son lo mejor de lo mejor en TypeScript. Ahora, necesito decirles que lo siento. Lo siento porque han tenido charlas fantásticas de oradores fantásticos. Ahora, voy a aplastar sus sueños y destruir sus esperanzas porque esta no va a ser una charla divertida. He hecho una buena cantidad de desarrollo con TypeScript. He escrito dos libros al respecto, uno de los cuales es TypeScript, las partes buenas. Así es como funciona el sistema de tipos para los desarrolladores de JavaScript. El otro es TypeScript Couple donde tenemos 100 problemas reales que vamos a resolver juntos. Y a lo largo de mi viaje, siempre comienzo con este ejemplo donde TypeScript es absolutamente perfecto. Tengo estos códigos de JavaScript. No se preocupen por lo que hace, pero es solo JavaScript. El navegador lo ejecuta. Simplemente no funciona. No hay ningún error que se esté lanzando. Nada te dice qué está mal. Se ejecuta, no lanza ningún error, pero no produce los resultados correctos. Y para ejemplos como ese, TypeScript es fantástico porque TypeScript, justo cuando lo activo, encuentra alrededor de, no sé, 10 errores en 15 líneas de código. Eso es para lo que estamos aquí. Ese es el propósito de TypeScript. Pero eso no es de lo que voy a hablar hoy. Hoy, hablo sobre lo totalmente opuesto. Voy a mostrarles un ejemplo con el que TypeScript está totalmente de acuerdo. Simplemente estamos obteniendo algunos datos de una API y concatenándolos con algo más. Y TypeScript dice, bueno, los tipos coinciden. Este es un buen código. Se compila, puedes enviarlo, y es muy probable que se bloquee en runtime. Ya sabes, en runtime, esas cosas que TypeScript se supone que debe prevenir. Vamos a repasar el código paso a paso.

2. Obtención de datos y manejo de errores

Short description:

La primera función obtiene datos de la API de Star Wars utilizando sobrecargas de funciones. Desenvolvemos los datos obtenidos y manejamos cualquier error de sintaxis potencial. Luego concatenamos arrays de personas o especies utilizando el método push, y finalmente, creamos un nuevo array de personas y añadimos especies a él. Este programa tiene alrededor de 10 líneas de código y ahora abordaremos los problemas paso a paso, comenzando con el núcleo de nuestra estructura.

La primera función obtiene data. La llamamos list entries, y tienes dos ... tienes dos sobrecargas de funciones que definen una API para ti y tus usuarios. Si obtienes un tipo de especies, entonces estás obteniendo una promesa de especies a cambio. Si estás obteniendo un tipo de personas, entonces estás obteniendo una promesa de personas a cambio. Estamos accediendo a la API de Star Wars, que es genial si quieres hacer cualquier prueba de rest. Y tienes una API muy personalizada para que realmente sepas lo que deberías obtener a cambio. Luego tienes la tercera sobrecarga de función, que es la implementación de la función real para ti. A continuación, estamos obteniendo data y dado que tiene alguna información meta, la estamos desenvolviendo. Solo estamos interesados en los resultados. Una cosa que es muy interesante acerca de esta línea de código es que estamos haciendo algo, lo siento, que estamos haciendo algo de manejo de errores. Así que hay una parte donde decimos, bueno, esa llamada result.JSON en la línea tres podría salir mal. Así que es mejor atrapar ese error de sintaxis. ¿Qué pasa si no obtenemos ningún JSON de vuelta? Fantástico. Cinco líneas de código para esa función, tres líneas de información de tipo. La siguiente es una línea. Solo la formateé un poco para esta diapositiva. Luego estamos concatenando una promesa de un array de personas o especies a otra lista de array de personas o especies. Así que estamos concatenando esos dos con el método push de un array. Y finalmente, estamos llamando así que estamos creando un nuevo array de personas y estamos añadiendo especies al array de personas. Muy bien. Este es nuestro programa. Son alrededor de, no sé, 10 líneas reales de código, un par de información de tipo. Y quiero preguntarte si miras el programa entero, ¿sabes qué está yendo mal o sabes qué se supone que debe ir mal? Entonces, bueno, creo que todo. ¿Y dónde va mal? En todas partes. ¿Y cuándo va mal? Sí, uno por uno, porque somos de un solo hilo. Pero no te preocupes, vamos a pasar por ello paso a paso. Ahora vamos a mirar todos nuestros problemas. Problema número uno en el capítulo uno,

3. Límites de TypeScript y Operaciones Inseguras

Short description:

Estamos obteniendo datos de la API de Star Wars y desenvolviendo un objeto JSON. Sin embargo, hay una mentira en la anotación de tipo. El tipo any de TypeScript nos permite eludir la comprobación de tipos, lo que puede llevar a errores al asignar any a un tipo específico. TypeScript expone los límites entre los tipos bien diseñados y el mundo real, donde las entradas externas necesitan alinearse con nuestros tipos. Estas operaciones inseguras destacan la necesidad de un manejo cuidadoso de la entrada del usuario, la E/S de red y los datos de la API.

una cola de fetch. Veamos el núcleo de nuestra primera estructura. Si lo miras, es maravilloso. Solo estamos obteniendo algunos data de la API de Star Wars y luego estamos llamando a result.json. Así que tenemos un objeto JSON y lo estamos desenvolviendo. Pero hay una pequeña mentira escondida en la línea número tres. Esta anotación de tipo, dejemos que data de tipo matter people, simplemente funciona porque la llamada a result.json devuelve una promesa de any. Y ya conoces any. Any es el tipo despreocupado en TypeScript. Any dice que no estoy haciendo ninguna comprobación de tipo en absoluto. Tú como desarrollador, sabes mejor. Y dado que estamos asignando any a matter of people, las cosas se rompen. Porque TypeScript entonces piensa que tú sabes mejor y sabes que el resultado o que el resultado JSON de result debería ser matter of people. Pero esto es solo hecho por ti mismo. Ningún comprobador de tipos te ayuda con ese problema. Y lo que estamos viendo aquí es TypeScript en sus límites donde la materia de tus tipos, ya sabes, que trabajan bien juntos, diseñaste cómo deberían ser se encuentra con el mundo real. Cuando tienes entrada de usuario, cuando tienes E/S de red, cuando tienes cosas de las APIs. Esto es algo desde el exterior entra en tu mundo de tipos y necesitas asegurarte de que esas cosas se alineen. Y TypeScript es una forma muy agradable de mostrar esos límites o mostrar cuando surgen esos problemas de límites. Me gusta llamar

4. Palabras clave para doblar el sistema de tipos

Short description:

Tenemos palabras clave como la afirmación de tipo y la función es dado que nos permiten doblar el sistema de tipos a nuestra voluntad.

esas operaciones inseguras. Y tenemos palabras clave para eso. Tenemos, por ejemplo, una afirmación de tipo. Entonces, en lugar de hacer una anotación de tipo, podemos decir que result.json debería ser meta people y esta es una afirmación de tipo explícita de nosotros donde estamos doblando el sistema de tipos. Lo mismo con la función es dado donde decimos, está bien, si estoy obteniendo un número en y es de uno a seis, entonces sé que es de tipo dado y puedo doblar el sistema de tipos. Puedo decir sistema de tipos, sé mejor que tú. Lo mismo con las firmas de afirmación. Y todos esos

5. Doblando el Sistema de Tipos

Short description:

Entonces, si te pregunto cuál de esas dos cosas demuestra mejor que el sistema de tipos se está doblando un poco, es el número dos. Sería mejor en ese caso, si result.json no produjera una promesa de any, sino más bien una promesa de desconocido. Desconocido te dice, por favor revisa todo antes de proceder. El tipo desconocido no es asignable al tipo meta people. Aquí es donde necesitas hacer comprobaciones adicionales. Problema uno encontrado. Problema uno resuelto. Veamos el problema dos. El tema es oscuro y lleno de errores.

palabras clave. Para nosotros, señalan que estamos doblando el sistema de tipos a nuestra voluntad. Entonces, si te pregunto cuál de esas dos cosas demuestra mejor que el sistema de tipos se está doblando un poco, es el número dos, porque puedes hacer una búsqueda de texto completa para la palabra clave como, y encuentras todas las posiciones, todos los lugares en tu código donde estás doblando el sistema de tipos a tu voluntad. El número uno es solo una afirmación de tipo. Nunca vas a descubrir que estás teniendo any en el lado derecho. Y de repente se convierte en un asunto de personas en el lado izquierdo. Entonces, lo que queremos es en realidad el número dos, pero el problema es que las anotaciones de tipo con any simplemente funcionan y nada nos impide hacerlo. TypeScript está totalmente contento con eso. Sería mejor en ese caso, si result.json no produjera una promesa de any, sino más bien una promesa de desconocido porque desconocido es el hermano cauteloso de any. Desconocido es el hermano cauteloso de any. Desconocido te dice, por favor revisa todo antes de proceder. Y podemos decirle a TypeScript que use desconocido en lugar de any. Con una pequeña cosa llamada fusión de declaraciones. Ninguna interfaz en TypeScript está nunca cerrada. Tú siempre puedes agregar nuevos métodos a ella. Esto es, en primer lugar, para mantener un registro de las versiones de ECMAScript es fantástico. En segundo lugar, también para que parchees cosas según las necesidades de tu navegador o las necesidades de tu entorno. Así es como gQuery maneja los plugins, por ejemplo. Y cómo TypeScript trabaja con el constructor de objetos y lo que sea. Y puedes decirle a TypeScript, la interfaz body, que es la única interfaz de la que nuestro resultado obtiene sus métodos, tiene otro método trace de promesa desconocida. Y como es el último, como lo añadiste en la última posición, esto anula los otros. Tienes otra sobrecarga de función que ahora devuelve una promesa de desconocido en lugar de una promesa de any. Y si añades esas tres líneas de código, entonces de repente estás obteniendo un error. Estás obteniendo un error y TypeScript te dice, espera un segundo, el tipo desconocido no es asignable al tipo meta people. Desconocido es el tipo cauteloso tipo, el tipo cauteloso de any mismo conjunto de áreas, pero muy cauteloso. Y aquí es donde necesitas hacer comprobaciones adicionales. Ya sea hacer una afirmación de tipo o tal vez usar algo como sal y asegúrate de que los data que obtienes son realmente los data que estás buscando. Genial. Problema uno encontrado. Problema uno resuelto. Veamos el problema dos. El tema es oscuro y

6. Capturando Errores de Sintaxis y Manejando Errores Desconocidos

Short description:

Esta línea de código captura errores de sintaxis, pero en JavaScript, cualquier cosa puede lanzar errores. Al agregar 'any' a una unión, capturamos cualquier error, lo que puede llevar a problemas potenciales al acceder a propiedades específicas. Para mitigar esto, use la bandera de compilador 'unknown' en las cláusulas catch y realice comprobaciones de instancia. Esto asegura que el error sea desconocido por defecto y permite un manejo adecuado de tipos de error específicos.

lleno de errores. Este es tan interesante. En esta línea de código, estamos capturando un error de sintaxis. El desarrollador fue muy astuto porque pensó que result.json podría lanzar un error de sintaxis y tienen razón. Si no obtienes ningún JSON de vuelta, es un error de sintaxis y entonces puedes capturar el error y tal vez devolver un array vacío o lo que sea. Usa algo para mitigar ese error.

Simplemente estoy lanzando otro error. ¿A quién le importa? Pero, ya sabes, queremos asegurarnos de que estamos capturando ese error de sintaxis. El problema es que en JavaScript, cualquier cosa puede lanzar errores en cualquier lugar. Los errores pueden suceder todo el tiempo y es por eso que el desarrollador añadió any a una unión. De nuevo en JavaScript, todo puede lanzar. Puedes lanzar el número dos, puedes lanzar undefined, puedes lanzar berrinches como mi hijo de dos años. Básicamente, JavaScript y mi hijo de dos años son lo mismo. En JavaScript, todo lanza y no sé de dónde viene. Mi hijo lanza berrinches y no sé de dónde vienen. Pero de todos modos, si miras esa línea, el pequeño any en la unión de un error de sintaxis, debería decirnos que esto es lo que realmente está sucediendo. O tienes un error de sintaxis o tienes cualquier error. Porque, ya sabes, solo tienes en algún lugar un error de sintaxis, o en algún lugar un error de tipo o lo que sea y tu programa se bloquea. Así que es cierto. La afirmación aquí es absolutamente cierta. El problema es que si pones any a una unión con algo más, estás obteniendo any de nuevo. Ya sabes, el tipo despreocupado que, ya sabes, desactiva la comprobación de tipos para ti. Así que básicamente estamos capturando cualquier cosa, lo que significa que si accedes a e.message en este punto, eso podría salir mal. Así que solo imprime undefined ahora, pero ¿qué pasa si haces algo con el mensaje, como convertirlo a mayúsculas o lo envías a algún lugar que espera un valor definido. Y puedes resolver esto de nuevo con una pequeña bandera de compilador llamada unknown en las cláusulas catch y haces comprobaciones de instancia más tarde. Así que activas la bandera, usas unknown y capturas variables. Entonces tu error es desconocido por defecto. Así que no necesitas capturar un error de sintaxis o cualquier cosa o lo que sea. Es desconocido por defecto. Y entonces puedes hacer comprobaciones, comprobaciones de instancia en el error de sintaxis para llegar a las propiedades reales de un error de sintaxis. Y así es como mitigas este problema.

7. Sobrecarga de Funciones y Desajuste de Tipos

Short description:

El problema con la sobrecarga de funciones es que los tipos pueden no reflejar con precisión los valores devueltos reales. En este caso, los tipos indican que obtenemos especies, pero en realidad, solo trabajamos con personas. Si los tipos y los valores devueltos reales son diferentes, puede llevar a acceder a propiedades inexistentes.

Entonces, problema número dos, solución de manejo de errores a las comprobaciones de instancia. Problema número tres, la sobrecarga de métricas. Ahora veamos esas sobrecargas de funciones de nuevo. Tenemos tres sobrecargas de funciones. Dos son para la interfaz para tus usuarios como tipo de especies devuelve promesa de especies, tipo de personas devuelve promesa de personas. Y luego tienes la firma de implementación más amplia, ya sabes, una que puedes trabajar realmente si obtienes ya sea tipo de personas, tipo de especies de personas o tú, y luego devuelves el array de personas o el array de especies. Uno de esos array de personas o especies. Bien. El problema aquí es que si miras esa línea de código, lo único que devuelvo son personas. No estoy devolviendo especies, pero los tipos me dicen que obtengo especies. El código me dice que solo devuelvo personas, por lo que puedo solicitar especies en mi código y el sistema de tipos me dice, bueno, todo es especies, pero en realidad, solo estoy trabajando con personas. Y si esos dos tipos son diferentes, bueno, entonces tienes un gran problema porque entonces

8. Modelos Funcionales y Verificaciones de Tipo

Short description:

Profundicemos en los modelos funcionales. Se realizan dos verificaciones de tipo: una para el uso y otra para la implementación. Las verificaciones de uso aseguran que todo en la sección de uso esté cubierto en la sección de implementación. La verificación de implementación valida el cuerpo de la función contra la firma de implementación. Sin embargo, existe una desconexión entre el cuerpo de la función, la firma de implementación y la firma de uso, lo que puede llevar a una cobertura incompleta. Los tipos condicionales pueden utilizarse como solución, pero introducen complejidad y requieren comprobaciones adicionales.

estás accediendo a propiedades que no existen. Bien, entonces veamos esos modelos funcionales en detalle. Podemos dividirlo. Entonces, si tienes modelos funcionales, siempre dos para el uso y el tercero es para la implementación. Y se realizan dos verificaciones de tipo. Primero de todas, todas esas verificaciones de uso comprueban si están siendo cubiertas por la implementación. Entonces no puedes escribir nada en la sección de uso que no esté cubierto en la sección de implementación. Esto es lo que está sucediendo aquí. Entonces, si añado especies y personas a kind, entonces también necesito asegurarme de que la firma de implementación se ocupa de ambos también. Puedes usar una unión o usar un tipo de variable como string. Y lo mismo con el tipo de retorno. Lo mismo. Esta es la primera verificación de tipo . La segunda verificación de tipo es entre la implementación en el cuerpo de la función. Entonces miras la firma de implementación y todo lo que escribes en el cuerpo de la función será verificado contra la firma de implementación. Entonces, esos dos mundos serán verificados pero nada verifica si tu implementación realmente cubre todas las entradas de uso. Nada lo verifica. Y este es el gran problema con las sobrecargas funcionales. Entonces, en primer lugar, genial, estás obteniendo una API a medida . El problema es que, bueno, hay una desconexión entre el cuerpo de la función, la firma de implementación y la firma de uso porque no se verifica todo. Son solo dos verificaciones de tipo diferentes que ocurren. Una solución para eso es hacer tipos condicionales. Los tipos condicionales, sabes, puedes definir básicamente una API similar. Ahora tengo aquí un tipo de retorno donde digo, bueno, si estoy obteniendo especies, entonces retorno especies. Si estoy obteniendo personas, retorno personas. De lo contrario, nunca, esto nunca funcionará. No uses nada más que especies o personas. Y entonces puedo usar genéricos, usar mi tipo condicional, y de repente estoy obteniendo un error porque los tipos condicionales son muy complejos. El cuerpo de la función no puede ser validado contra el tipo de retorno de un tipo condicional, o el tipo de retorno condicional. Entonces, estoy obteniendo un error donde digo, los arrays de personas o especies no son asignables al retorno de T.

9. Afirmaciones de Tipo, Operaciones Inseguras y Genéricos

Short description:

Ahora necesito hacer afirmaciones de tipo y operaciones inseguras. Destaco un problema potencial en mi código. Concateno dos arrays, pero el tipo de la lista permanece igual incluso después de añadir especies a ella. Esto se debe a que la lista original se muta, y TypeScript no destaca estas mutaciones. Para solucionar esto, siempre añade genéricos. Los genéricos bloquean tu tipo en algo concreto. Al usar genéricos, TypeScript inferirá correctamente el tipo de la lista basándose en la entrada.

Ahora necesito hacer comprobaciones extra. Ahora necesito hacer afirmaciones de tipo. Ahora necesito hacer operaciones inseguras. Ahora destaco un problema potencial en mi código. Estoy obteniendo un error, y esto es para lo que estamos aquí. Ahora, a mi favorito, capítulo 4, la inesperada virtud de la ignorancia. Veamos esta única línea de código, y la firma de tipo alrededor de ella. Así que, estoy obteniendo dos parámetros. Uno es un array de personas o especies. El otro es una promesa de un array de personas o especies. Luego concateno los dos. Fantástico, eso es todo lo que está pasando. Simplemente tomo dos arrays, los concateno. Hermoso. Luego estoy creando un array de personas, y luego estoy llamando a await las entradas de la lista y las entradas de la lista de especies. Así que estoy concatenando el array de personas con el array de especies. ¿Cuál es el tipo de lista después de las entradas de la lista? Sigue siendo personas. El tipo de lista sigue siendo personas, a pesar de que estoy añadiendo especies al array. Así que esto es, no tengo palabras para eso, lo siento mucho, no tengo palabras para eso, solo animations, pero esto es hermoso. Este es un error tan hermoso y me molesta tanto que suceda, pero lo que está pasando aquí es lo siguiente, que todos los contratos se cumplen. Así que si tengo una lista que es un array de especies de personas, entonces puedo añadir un array de personas a ella. Y si tengo otra lista de array de personas, entonces puedo añadir un array de especies a ella. El problema es que la lista original está siendo mutada y en TypeScript no existe nada para destacar esas mutaciones por ejemplo de arrays, o lo que sea. Así que el tipo no cambia después. Este es un problema. Pero hay otra solución para eso. Si te encuentras con cosas como esta, siempre añade genéricos. Los genéricos son hermosos porque los genéricos tienen una muy fantástica característica que es que bloquean tu tipo en algo concreto. Así que lo que estoy haciendo aquí ahora es que en lugar de tomar el tipo amplio de personas o especies, estoy tomando un parámetro de tipo genérico T que extiende un array de personas o especies entonces tengo una lista de T y tengo una promesa de T. Hago lo mismo. Es solo el mismo código pero ahora cuando creo una lista de personas y pongo esa lista en las entradas de la lista,

10. Limitaciones de TypeScript y Soluciones

Short description:

Por lo tanto, lo bloquea al subconjunto. Y en el momento en que lo bloquea al subconjunto de array de personas o especies, se da cuenta de que lo que estoy obteniendo aquí no es del mismo tipo que la lista. Esto es un error. Ahora podemos actuar. Todo mitigado. Cada problema potencial ahora tiene una solución. Mentiras, malditas mentiras y TypeScript. Hemos encontrado cuatro problemas y cuatro mitigaciones. La fusión de declaraciones de interfaz es fantástica, a menos que accidentalmente te fusiones con globales.

TypeScript bloquea T al array de personas. Por lo tanto, lo bloquea al subconjunto. Ya no está tomando el conjunto más amplio. Lo bloquea al subconjunto. Y en el momento en que lo bloquea al subconjunto de array de personas o especies, en el momento en que lo bloquea a ese subconjunto, se da cuenta de que lo que estoy obteniendo aquí no es del mismo tipo que la lista. Entonces me dice, espera un segundo, el argumento del tipo promesa especies, uh, promesa de especies no es asignable al tipo de parámetro de promesa de personas porque la lista define el tipo concreto. Sabes, esto es un error. Esto es para lo que estamos aquí. Ahora podemos actuar. Vale. Todo mitigado. Cada problema potencial ahora tiene una solución. Por favor, entra en el último capítulo. Mentiras, malditas mentiras y TypeScript. Hasta ahora hemos encontrado cuatro problemas y hemos encontrado cuatro mitigaciones. Usamos la fusión de declaraciones para parchear las suposiciones hechas por la biblioteca estándar. Usamos comprobaciones de instancia y desconocido para reducir los tipos de error. ¡Genial! Usamos tipos condicionales en lugar de sobrecargas de funciones para resaltar operaciones inseguras y cuarto, hermoso, usamos genéricos para reducir a lo específico. Cuatro problemas para soluciones y todas las soluciones solo tienen más mentiras. Lo siento mucho. Acabo de contarte más mentiras. En primer lugar, la fusión de declaraciones de interfaz es fantástica. Puedes extender el espacio de nombres global y añadir más propiedades a él si tu software lo necesita, si tus bibliotecas lo necesitan, si tienes Google Analytics en la interfaz de ventana, bueno, entonces, puedes simplemente añadirlo a la interfaz de ventana. Eso es lo que haces. Es genial a menos que estés definiendo una nueva interfaz que accidentalmente te fusionas con el global, como los datos del formulario aquí. Esto ya le ha pasado a tanta gente. Constantemente recibo mensajes de personas en Twitter o Nestled o donde sea, donde dicen, tuve exactamente el mismo problema porque estaba definiendo mis datos de formulario con la interfaz de datos de formulario, y ¿adivina qué? Es un global y nada me dice que es un global. De repente, estás obteniendo más métodos como .get, .set. ¿De dónde viene esto? Bueno, viene de una interfaz de datos de formulario global con la que accidentalmente me fusioné. Así que la fusión de declaraciones es genial a menos que te fusiones accidentalmente con globales. Ahora algo que hace que mis uñas de los pies se levanten,

11. Clase R, Clase B, y Verificaciones de Instancia

Short description:

Tengo dos clases, clase R y clase B, ambas tienen una propiedad numérica. Una se llama A, la otra se llama B, y luego tengo una función de hacer algo donde estoy obteniendo una unión para A o B. Así que es A o es B. Y estoy haciendo verificaciones de instancia.

es hilarante. Tengo dos clases, clase R y clase B, ambas tienen una propiedad numérica. Una se llama A, la otra se llama B, y luego tengo una función de hacer algo donde estoy obteniendo una unión para A o B. Así que es A o es B. Y estoy haciendo verificaciones de instancia. Así que estoy haciendo P instancia de A, entonces debería ser A. Así que estoy registrando A y en la rama else es B. Así que TypeScript me dice que es B y estoy registrando P.B. Bien. Así es como se supone que debe funcionar. Hermoso. Así que ahora puedo crear nuevas instancias de A, nuevas instancias de B. Estoy haciendo verificaciones de instancia. Todo está como debería ser.

12. El sistema de tipos estructurales de TypeScript

Short description:

El sistema de tipos estructurales de TypeScript permite que los objetos que se asemejan a instancias de una cierta clase pasen las verificaciones de tipo, incluso si no se crean con la palabra clave 'new'. Esto puede llevar a un comportamiento inesperado al pasar estos objetos a funciones. TypeScript puede inferir incorrectamente su tipo y causar problemas. Es importante estar consciente de esta limitación en el sistema de tipos de TypeScript.

Y luego te das cuenta de que TypeScript tiene un sistema de tipos estructurales y que puedes introducir un objeto que simplemente parece una instancia de A y que pasará la verificación de tipo. Entonces, haz algo con este objeto, A42, pasa la verificación de tipo. Pero si este objeto entra en la función 'haz algo', no será una instancia de A. No será una instancia porque no se está creando con la palabra clave 'new'. Es solo algo que se parece a una instancia de A. Y a TypeScript le parece bien. Entonces, esta verificación de instancia de A falla. Estás en la rama else. Typescript piensa que eres B. Pero en realidad, eres un objeto como A. Entonces sí, los objetos de instancia son geniales hasta que te das cuenta de que TypeScript es de tipado estructural.

13. Complejidad de los Tipos Condicionales y Genéricos

Short description:

Sí. Tercer problema. Los tipos condicionales son geniales a menos que se vuelvan demasiado complejos. Requieren documentación adicional, cuidado y pruebas exhaustivas. Es importante revisar dos veces su implementación, documentar todo y escribir casos de prueba. Los genéricos también pueden causar problemas si el parámetro de tipo genérico no está explícitamente anotado. Por lo tanto, recuerda manejar los tipos condicionales y genéricos con precaución.

Sí. Tercer problema. Los tipos condicionales son geniales a menos que... Lo siento mucho. En serio, lo siento si miras eso. No tengo idea de lo que hace. Um, de los creadores de las expresiones regulares llega el SQL que nadie pidió. No, lo siento mucho. Um, esto aquí es, supongo que se trata de sobrecargas de funciones que ocurren. Um, no lo sé. Yo he escrito este tipo. Uh, entonces, lo hice yo mismo y no podría decirte qué hace porque hace solo una semana olvidé totalmente lo que hice. Um, he escrito un libro sobre eso. Así que esto es parte de mi libro para explicar qué está pasando, pero quién, así que si usas tipos condicionales, conoce su complejidad, son geniales porque puedes hacer muchas cosas con ellos. Son muy poderosos. Es increíble lo que puedes hacer con ellos, pero requieren documentación adicional y cuidado extra. Y tú, no estás aquí para trabajar para lo último y lo mejor y para lo más, lo más, um, Código Vudú que puedes hacer. Uh, no hay magia en la codificación. Necesitas trabajar con personas. Necesitas trabajar contigo mismo o necesitas trabajar con tus colegas y si esto entra en tu base de código, revisa dos veces lo que está pasando allí. Documenta todo, escribe casos de prueba con él. Puedes escribir casos de prueba de tipo. Puedes hacer eso. Asegúrate de que todo aquí esté documentado y etiquetado de manera adecuada y que las pruebas, uh, resisten el paso del tiempo. Um, entonces sí, los tipos condicionales son geniales a menos que descubras que en realidad son bastante complejos y el último botón. Estos son genéricos. Los creo para ti, explícitamente hago esto, escribe como debería ser. Siempre puedes explícitamente, um, uh, anotar el parámetro de tipo genérico y luego todo vuelve a explotar. Entonces sí, cuatro problemas, cuatro soluciones,

14. Epílogo: Las mentiras que nos contamos a nosotros mismos

Short description:

Amo TypeScript. Es el segundo mejor lenguaje con el que he trabajado y me hace productivo. Nos decimos mentiras sobre TypeScript siendo 100% seguro en cuanto a tipos y que nos respalda. Como ingenieros de software, nuestra tarea principal es tomar decisiones y validar compensaciones. TypeScript es solo una herramienta, y necesitamos saber qué está pasando debajo. El equipo de TypeScript es bueno tomando esas decisiones y compensaciones.

problemas anteriores. Vamos por el epílogo. Muy bien, amigos. Les dije, lo siento. Esto, esto no fue la charla divertida. Esto fue solo problemas y más problemas y mentiras, y lamento mucho eso. Um, y podrías pensar, sabes, he escrito dos libros sobre TypeScript. Estoy haciendo consultoría sobre TypeScript. Estoy trabajando con muchos equipos en TypeScript y estoy creando un runtime de TypeScript, um, como, como, como, pero, um, pero internamente, ¿qué pienso de TypeScript? ¿Qué pienso de TypeScript después de encontrar todos esos grandes problemas? Y tengo que decir, oh, amo jodidamente TypeScript. En serio. Todavía es el segundo mejor lenguaje con el que tuve el placer de trabajar. Es muy divertido y me hace muy productivo. Y tú no puedes discutir con eso. TypeScript te hace productivo. Um, sabes, esta charla no se llama las mentiras que TypeScript nos cuenta, esta charla se llama las mentiras que nos contamos a nosotros mismos usando TypeScript. Um, y hay muchas mentiras que nos contamos a nosotros mismos. Nos decimos la mentira de que TypeScript es 100% seguro en cuanto a tipos. Um, nos estamos diciendo la mentira de que podemos, podemos olvidarnos de nuestro código porque TypeScript nos respalda. Um, y tal vez nos estamos diciendo a nosotros mismos la mentira más grande de que pensamos que estamos aquí para escribir código. Y no lo creo. No creo que estemos aquí para escribir código. Creo que nosotros, como ingenieros de software, estamos aquí para tomar decisiones. Y estamos aquí para validar las compensaciones de cada decisión que estamos tomando. Um, TypeScript es solo una herramienta en la caja. El código que escribes y todo lo que obtienes, por ejemplo, de Co-Pilot o Stack Overflow o donde sea. Si lo pones en tu base de código, tomas la decisión de que este código es lo suficientemente bueno para ponerlo en tu base de código. Y esto es lo que debería ser la tarea principal. Um, las herramientas solo pueden ayudarte a tomar decisiones, pero aún necesitas saber qué está pasando debajo. Y sabes, ¿quién es realmente bueno tomando esas decisiones y compensaciones? El equipo de TypeScript. Esta es una página del wiki en GitHub, um, que define metas y no metas. Y creo que las no metas son muy interesantes, porque hay una línea que básicamente te dice la razón de todo lo que acabas de ver.

15. Compromisos y pragmatismo en TypeScript

Short description:

Un objetivo no es aplicar un sistema de tipos sólido y aprobablemente correcto. En cambio, TypeScript prioriza la productividad. La popularidad de TypeScript proviene de su enfoque en la productividad sobre un sistema de tipos demostrablemente correcto. Si usas TypeScript, ámalo, pero ten en cuenta el compromiso. Es tu deber aprender el sistema de tipos y tomar decisiones bien fundamentadas. Sé pragmático, cuestiona todo y elige lo que mejor funcione para ti y tu equipo. ¡Gracias por escuchar!

Un objetivo no es aplicar un sistema de tipos sólido y aprobablemente correcto. En cambio, quieren encontrar un equilibrio entre la corrección y la productividad. Y todos esos pequeños errores que acabas de ver provienen exactamente de esa línea. Um, ponen la productividad primero. Y con eso, sí, puede que haya un par de parches donde, ya sabes, las cosas podrían no terminar como deberían ser. Um, pero aún así, tú tomas la decisión de poner la línea en tu código. Así que eres el responsable de ese TypeScript, solo necesitas saber sobre el compromiso. Y hay un gran compromiso en TypeScript en que, ya sabes, las cosas podrían no ser demostrablemente correctas en el sistema de tipos. Y podrías decir, pero, pero, bueno, ¿por qué, por qué nos molestamos si ellos, si ellos no lo hacen demostrablemente correcto porque el objetivo principal siempre fue hacer a los desarrolladores productivos. Um, di la misma charla frente a 4,000 personas, um, en el Congreso Mundial de Desarrolladores V8. Y les hice dos preguntas a la audiencia. La pregunta número uno fue quién está, quién está usando TypeScript en una sala con 4,000 personas? Más del 90% levantaron sus manos. Y luego les pregunté, ¿alguien recuerda un sistema de tipos llamado Flow? Y eran tres personas, tres personas de 4,000 recuerdan un sistema de tipos llamado Flow, que fue la respuesta de Facebook a TypeScript. Muy similar en sintaxis, muy similar en características, pero los chicos de Flow tenían el objetivo de tener un sistema de tipos demostrablemente correcto y así matar la productividad para todo lo demás. Y vemos lo que ha prevalecido con el tiempo. Por mucho que me guste Flow y conozca a gente del equipo de Flow, sé en qué trabajaron y cómo se acercaron a ellos. Es un hermoso sistema de tipos. Pero esta pequeña decisión de poner la productividad primero es lo que hizo que TypeScript fuera tan popular al final. Y este es el punto de mi charla. El punto de mi charla es que, si usas TypeScript, por favor ámalo tanto como yo porque, en serio, amo TypeScript y es genial trabajar con él. Pero ten en cuenta el compromiso que estás haciendo. Ten en cuenta que el sistema de tipos podría funcionar de manera diferente a lo que esperabas y aún es tu deber aprenderlo.

No quita la responsabilidad de aprender un lenguaje de programación solo porque obtienes una herramienta tan excelente. Y esto me lleva al aprendizaje que quiero transmitirte, que es lo único que debes llevar a casa. Sé pragmático y consciente. Elige lo que mejor funcione para ti y tu equipo. Y si no tienes un equipo, siempre tienes a tu yo futuro con el que necesitas trabajar. Nunca codificas solo. No escuches consejos dogmáticos. Ya sabes, es tan fácil hacer, no sé, supongo que es TikTok donde tienes que, no sé, o tuitear o lo que sea, que te da ese hermoso, fantástico consejo que mata todo lo demás. Pero entonces, ya sabes, es solo otra decisión que alguien más tomó por ti. No escuches consejos dogmáticos. Siempre cuestiona todo, validarlo contra lo que necesitas hacer. Sé pragmático, sé consciente, toma decisiones, bien informado. Y con eso, quiero decir, muchas gracias por escucharme. Muchas gracias por conocerme. Espero que te hayas divertido tanto como yo. Muchas gracias.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

TypeScript and React: Secrets of a Happy Marriage
React Advanced Conference 2022React Advanced Conference 2022
21 min
TypeScript and React: Secrets of a Happy Marriage
Top Content
TypeScript and React are inseparable. What's the secret to their successful union? Quite a lot of surprisingly strange code. Learn why useRef always feels weird, how to wrangle generics in custom hooks, and how union types can transform your components.
React's Most Useful Types
React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
Top Content
We don't think of React as shipping its own types. But React's types are a core part of the framework - overseen by the React team, and co-ordinated with React's major releases.In this live coding talk, we'll look at all the types you've been missing out on. How do you get the props type from a component? How do you know what ref a component takes? Should you use React.FC? And what's the deal with JSX.Element?You'll walk away with a bunch of exciting ideas to take to your React applications, and hopefully a new appreciation for the wonders of React and TypeScript working together.
Stop Writing Your Routes
Vue.js London 2023Vue.js London 2023
30 min
Stop Writing Your Routes
The more you keep working on an application, the more complicated its routing becomes, and the easier it is to make a mistake. ""Was the route named users or was it user?"", ""Did it have an id param or was it userId?"". If only TypeScript could tell you what are the possible names and params. If only you didn't have to write a single route anymore and let a plugin do it for you. In this talk we will go through what it took to bring automatically typed routes for Vue Router.
Making Magic: Building a TypeScript-First Framework
TypeScript Congress 2023TypeScript Congress 2023
31 min
Making Magic: Building a TypeScript-First Framework
I'll dive into the internals of Nuxt to describe how we've built a TypeScript-first framework that is deeply integrated with the user's IDE and type checking setup to offer end-to-end full-stack type safety, hints for layouts, middleware and more, typed runtime configuration options and even typed routing. Plus, I'll highlight what I'm most excited about doing in the days to come and how TypeScript makes that possible not just for us but for any library author.
Full-stack & typesafe React (+Native) apps with tRPC.io
React Advanced Conference 2021React Advanced Conference 2021
6 min
Full-stack & typesafe React (+Native) apps with tRPC.io
Top Content
Why are we devs so obsessed with decoupling things that are coupled nature? tRPC is a library that replaces the need for GraphQL or REST for internal APIs. When using it, you simply write backend functions whose input and output shapes are instantly inferred in your frontend without any code generation; making writing API schemas a thing of the past. It's lightweight, not tied to React, HTTP-cacheable, and can be incrementally adopted. In this talk, I'll give a glimpse of the DX you can get from tRPC and how (and why) to get started.
Faster TypeScript builds with --isolatedDeclarations
TypeScript Congress 2023TypeScript Congress 2023
24 min
Faster TypeScript builds with --isolatedDeclarations
Top Content
Type-checking a TypeScript codebase can be slow, especially for monorepos containing lots of projects that each need to use the type checker to generate type declaration files. In this talk, we introduce — for the very first time — a new TypeScript feature we are working on called “Isolated Declarations” that allows DTS files to be generated without using the type checker at all! This opens the door to faster declaration generation in TypeScript itself, as well as in external tools written in other languages such as ESBuild and swc. You'll see how to use this new option, and maybe (just maybe) you’ll be convinced about the benefits of explicit return types! Most importantly, we will show how Isolated Declarations enables parallel builds to spread work across your CPU cores to significantly improve the build speed of your TypeScript projects.

Workshops on related topic

React, TypeScript, and TDD
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Best Practices and Advanced TypeScript Tips for React Developers
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Deep TypeScript Tips & Tricks
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Top Content
Workshop
Josh Goldberg
Josh Goldberg
TypeScript has a powerful type system with all sorts of fancy features for representing wild and wacky JavaScript states. But the syntax to do so isn't always straightforward, and the error messages aren't always precise in telling you what's wrong. Let's dive into how many of TypeScript's more powerful features really work, what kinds of real-world problems they solve, and how to wrestle the type system into submission so you can write truly excellent TypeScript code.
Practice TypeScript Techniques Building React Server Components App
TypeScript Congress 2023TypeScript Congress 2023
131 min
Practice TypeScript Techniques Building React Server Components App
Workshop
Maurice de Beijer
Maurice de Beijer
In this hands-on workshop, Maurice will personally guide you through a series of exercises designed to empower you with a deep understanding of React Server Components and the power of TypeScript. Discover how to optimize your applications, improve performance, and unlock new possibilities.
 
During the workshop, you will:
- Maximize code maintainability and scalability with advanced TypeScript practices
- Unleash the performance benefits of React Server Components, surpassing traditional approaches
- Turbocharge your TypeScript with the power of Mapped Types
- Make your TypeScript types more secure with Opaque Types
- Explore the power of Template Literal Types when using Mapped Types
 
Maurice will virtually be by your side, offering comprehensive guidance and answering your questions as you navigate each exercise. By the end of the workshop, you'll have mastered React Server Components, armed with a newfound arsenal of TypeScript knowledge to supercharge your React applications.
 
Don't miss this opportunity to elevate your React expertise to new heights. Join our workshop and unlock the potential of React Server Components with TypeScript. Your apps will thank you.
Advanced TypeScript types for fun and reliability
TypeScript Congress 2022TypeScript Congress 2022
116 min
Advanced TypeScript types for fun and reliability
Workshop
Maurice de Beijer
Maurice de Beijer
If you're looking to get the most out of TypeScript, this workshop is for you! In this interactive workshop, we will explore the use of advanced types to improve the safety and predictability of your TypeScript code. You will learn when to use types like unknown or never. We will explore the use of type predicates, guards and exhaustive checking to make your TypeScript code more reliable both at compile and run-time. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Are you familiar with the basics of TypeScript and want to dive deeper? Then please join me with your laptop in this advanced and interactive workshop to learn all these topics and more.
You can find the slides, with links, here: http://theproblemsolver.nl/docs/ts-advanced-workshop.pdf
And the repository we will be using is here: https://github.com/mauricedb/ts-advanced
Mastering Node.js Test Runner
TestJS Summit 2023TestJS Summit 2023
78 min
Mastering Node.js Test Runner
Workshop
Marco Ippolito
Marco Ippolito
Node.js test runner is modern, fast, and doesn't require additional libraries, but understanding and using it well can be tricky. You will learn how to use Node.js test runner to its full potential. We'll show you how it compares to other tools, how to set it up, and how to run your tests effectively. During the workshop, we'll do exercises to help you get comfortable with filtering, using native assertions, running tests in parallel, using CLI, and more. We'll also talk about working with TypeScript, making custom reports, and code coverage.