La semana pasada vimos una pequeña introducción al mecanografiado y, en particular, hablamos sobre cómo este lenguaje que extiende JavaScript puede ayudarnos a crear un código más robusto. Debido a que esto fue solo una introducción, no hablé sobre algunas de las características de TypeScript que podría (y probablemente necesitar) usar en sus proyectos. Hoy le enseñaré cómo aplicar TypeScript en un proyecto real. Para hacer esto, comenzaremos analizando parte del código fuente de contenido NELI para comprender dónde comenzamos y qué limitaciones tenemos hoy. A continuación, mejoramos gradualmente el código JavaScript original agregando pequeñas mejoras incrementales hasta que tengamos un código completamente escrito.
Utilizando el código fuente de contenido de Nelio como base como probablemente ya sepa, Nelio Content es un complemento que le permite compartir el contenido de su sitio en las redes sociales. Además, también incluye algunas características que tienen como objetivo ayudarlo a generar constantemente mejor contenido en su blog, como un análisis de calidad de sus publicaciones, un calendario editorial para rastrear el contenido futuro que necesita escribir y así sucesivamente.

El calendario editorial del contenido de Nelio. El mes pasado publicamos la versión 2.0, un rediseño completo y un rediseño interno de nuestro complemento. Creamos esta versión utilizando todas las nuevas tecnologías que tenemos hoy en WordPress (algo de lo que hablamos recientemente en nuestro blog), incluida una interfaz React y una tienda Rodux.
Entonces, en el ejemplo de hoy, mejoraremos este último. Quiero decir, veremos cómo podemos presentar una tienda Rodux. Nelio Content Editor Calendar Selecters El calendario editorial es una interfaz de usuario que muestra las publicaciones de blog que hemos programado para todos los días de la semana. Esto significa que, al menos, nuestra tienda Rodux necesitará dos operaciones de consulta: una que nos diga las publicaciones que están programadas en un día determinado y otro que, dada una identificación de publicación, devuelve todos sus atributos. Suponiendo que haya leído nuestras publicaciones sobre este tema, ya sabe que un selector en Rodux recibe como primer parámetro la condición con toda la información de nuestra aplicación seguida de cualquier parámetro adicional que pueda necesitar. Entonces, los dos ejemplos de selectores en JavaScript serían así: función getPost (estado, id) {return States.posts [id]; } Function getPostsInday (estado, día) {return state.days [día] ?? []; } Si te preguntas dónde sé que un estado tiene las publicaciones y días de atributos, es bastante simple: porque yo soy el que definí. Pero es por eso que decidí implementarlos. Sabemos que queremos poder acceder a la información desde dos puntos de vista diferentes: publicaciones en un día o publicación por ID. Por lo tanto, parece tener sentido organizar nuestros datos en dos partes:
Por un lado, tenemos un atributo de publicaciones en el que enumeramos todas las publicaciones que obtuvimos del servidor y las guardamos en nuestra tienda Rodux. Lógicamente, podríamos haberlos guardado en una matriz y hacer una búsqueda secuencial para encontrar la publicación cuya identificación coincide con la esperada … pero un objeto se comporta como un diccionario, que ofrece búsquedas más rápidas.
Por otro lado, también debemos acceder a las publicaciones que están programadas en un día determinado. Una vez más, podríamos haber usado solo una matriz para almacenar todas las publicaciones y filtrarlas para encontrar las publicaciones que pertenecen a un día en particular, pero otro diccionario ofrece una solución de búsqueda más rápida. Si queremos un calendario dinámico, debemos implementar funciones que permitan nosotros para actualizar la información que nuestras tiendas almacenan. Para simplificar, propondremos dos métodos simples: uno que nos permite agregar nuevas publicaciones en el calendario y otra que nos permite cambiar los atributos de los existentes.
Las actualizaciones de una tienda Rodux requieren dos partes. Por un lado, tenemos acciones que indican el cambio que queremos hacer y, por otro lado, hay un reductor de que, dado el estado actual de nuestra tienda y una acción que se solicita, aplican los cambios necesarios en el estado actual . genera un nuevo estado. Entonces, teniendo en cuenta esto, estas son las acciones que podríamos tener en nuestra tienda: Function RegeneneWpost (post) {return {type: ‘recibe_new_post’, post,}; } Función UpdatePost (PostId, Attributes) {return {type: ‘update_post’, postid, atributes,}} y aquí el reductor:
Reductor de funciones (estado, acción) {estado = estado ?? {publicaciones: {}, días: {}}; Constids = object.Keys (state.posts); Switch (action.type) {case ‘recibe_new_post’; If (postids.includes (action.postid)) {return States; } return {publicaciones: {… state.posts, [action.post.id]: action.post,}, días: {… state.days, [action.post.day]: [… state .Days [action.post.day], action.post.id,],},}; casas ‘update_post’; If (! Postids.include (action.postid)) {State de retorno; } const post = {… state.posts [Action.Postid], … Action.Attributes,}; return {publicaciones: {… state.posts, [post.id]: post,}, días: {… object.keys (state.days) .acc, [día]: state.days [día] .Filter ((postid) => postid! == post.id),}), {}), [post.day]: [… state.days [post.day], post.id,],} ,}; } Estados de retorno; } ¡Tómese el tiempo para comprender todo y continúe! De JavaScript a TypeScript, lo primero que debemos hacer es traducir el código anterior a TypeScript. Bueno, dado que TypeScript es un Superset JavaScript, ya es … pero si copia y pega las funciones anteriores en TypeScript Playground, verá que el compilador se queja bastante porque hay demasiadas variables cuyo tipo predeterminado es. Entonces, primero, reparemos esto agregando explícitamente algunos tipos básicos. Todo lo que tenemos que hacer es agregar cualquier tipo a lo que sea “complejo” (como nuestra aplicación) y usar número o cadena o cualquier cosa que queramos a cualquier otra variable/argumento. Por ejemplo, el selector original de JavaScript:
Función getPost (estado, id) {return state.posts [id]; } Con tipos explícitos, typeScript se vería así: función getPost (estado: cualquiera, id: número): cualquiera | no afinado {return state.posts [id]; } Como puede ver, la acción de escritura simple de nuestro código (incluso cuando se usa “tipos genéricos”) ofrece mucha información con una mirada rápida; ¡Una mejora clara en comparación con el JavaScript básico! En este caso, por ejemplo, vemos que GetPost está esperando un número (un ID de publicación es un número entero, ¿recuerdas?) Y el resultado será algo si la publicación existe (alguna) o nada si hay (no afinado). Aquí tiene el enlace con todo tipo de código usando tipos simples, para que el compilador no se queje. Cree y use tipos de datos personalizados en TypeScript ahora que el compilador está satisfecho con nuestro código fuente, es hora de pensar un poco sobre cómo podemos mejorarlo. Para esto, siempre propongo comenzar modelando los conceptos que tenemos en nuestro campo.
Creando un tipo personalizado para publicaciones, sabemos que nuestra tienda contendrá por primera vez publicaciones, por lo que diría que el primer paso es modelar lo que es una publicación y qué información tenemos al respecto. Ya hemos visto cómo crear tipos personalizados la semana pasada, así que intentemos hoy con el concepto de publicación:
Escriba post = {id: número; Títulos: cadena; Autor: cadena; Día: cuerda; Estado: cadena; ISsticky: booleano; }; No es sorprendente aquí, ¿verdad? Una publicación es un objeto que tiene algunos atributos, como una identificación numérica, un título de texto, etc. Otra información importante que tiene cualquier tienda Rodux es, adivinó, su condición. En la sección anterior ya hemos discutido los atributos que tiene, así que definamos la forma básica de nuestro tipo de estados: type state = {publicaciones: cualquiera; Días: cualquiera; }; Mejorar el tipo de estados ahora sabe que los estados tienen dos atributos (publicaciones y días), pero no sabemos mucho sobre ellos porque pueden ser cualquiera. Dije que quería que ambos atributos fueran diccionarios. Es decir, dada una determinada consulta (una identificación de publicaciones para publicaciones o una vez para días), queremos los datos relacionados (una publicación o una lista de publicaciones respectivamente). Sabemos que podemos implementar un objeto usando un objeto, pero ¿cómo representamos un diccionario en TypeScript?
Si echamos un vistazo a la documentación de TypeScript, veremos que esto incluye varios tipos de utilidades para hacer frente a situaciones bastante comunes. Específicamente, hay un tipo llamado registro que parece ser el que queremos: nos permite ingresar una variable usando pares/valor de clave donde la clave tiene un cierto tipo y los valores son de tipo. Si aplicamos este tipo a nuestro ejemplo, llegaríamos a algo como esto: type state = {post: registro ; Días: registro ; }; Desde la perspectiva del compilador, el tipo de registro funciona de tal manera que, dado cualquier valor de claves (en nuestro ejemplo, número para publicaciones y cadenas para días), su resultado siempre será un objeto de tipo (en nuestro caso, un publicar o, respectivamente, un número []). El problema es que no queremos comportarse con nuestro diccionario: cuando buscamos una determinada publicación usando su identificación, queremos que el compilador sepa que es posible encontrar o no una publicación relacionada, lo que significa que el resultado puede ser ya sea una publicación. o indefinida. Afortunadamente, podemos resolver esto fácilmente usando otro tipo de utilidad, el tipo parcial: type state = {publicaciones: parcial <registro ; Días: parcial <registro <string ; }; Mejora de nuestro código con aliados tipo Eche un vistazo al atributo de publicaciones en nuestro estado … ¿qué ves? Un diccionario indexación de publicaciones de tipo de tipo, ¿verdad? Ahora imagine que revisa este código en el trabajo. Si cumple con dicho tipo, podría suponer que una serie de publicaciones de indexación es probablemente la identificación de publicaciones indexadas … pero esto es solo una suposición;
Debe revisar el código para asegurarse de él. ¿Y los días? “Listas de números de indexación de filas aleatorias”. No es muy útil, ¿no? Los tipos de mecanografiado nos ayudan a escribir un código más robusto debido a las verificaciones del compilador, pero ofrece mucho más que eso. Si usa tipos significativos, su código estará mejor documentado y será más fácil de mantener. Entonces, allemos aliados de los tipos existentes para crear tipos significativos, ¿verdad? Por ejemplo, sabiendo que las ID de publicación (número) y los datos (cadena) son relevantes para nuestro dominio, podemos crear fácilmente los siguientes tipos de type: type postid = número; Escriba día = cadena; Y luego reescribir nuestros tipos originales usando estos Allias: type post = {id: postid; Títulos: cadena; Autor: cadena; Día día; Estado: cadena; ISsticky: booleano; }; Type state = {Postes: parcial <registro ; Días: Parcialmente <Record ; }; Otro tipo de alias que podemos usar para mejorar la legibilidad de nuestro código es el tipo de diccionario, que “oculta” la complejidad del uso parcial y de registro detrás de una estructura conveniente: tipo diccionario = parcial <registro >; Hacemos el código fuente más claro: type state = {publicaciones: diccionario ; Días: Diccionario ; };

¡Y eso es! ¡Aquí! Con solo tres aliados simples, podríamos documentar el código de una manera claramente mejor que usar comentarios. Cualquier desarrollador que venga después de nosotros podrá saber, de un vistazo, que las publicaciones es un diccionario que indexa objetos de tipo post y que días es una estructura de datos que, dada un día, devuelve identificadores de publicación en la lista. Es genial, si me preguntas. Pero no solo las definiciones de tipos en sí mismas son mejores … si usamos estos nuevos tipos en todo nuestro código: Función GetPost (Estado: Estado, ID: PostId): Post | no afinado {return state.posts [id]; } También se beneficia de esta nueva capa semántica! Puede ver la nueva versión de nuestro código ingresado aquí. Por cierto, tenga en cuenta que los aliados de tipo son, desde el punto de vista del compilador, imposible de distinguir del tipo “original”. Esto significa que, por ejemplo, un postid y un número son completamente intercambiables. Por lo tanto, no espere que el compilador active un error si asigna un postid a un número o viceversa (como puede ver en este pequeño ejemplo);
TypeScript avanzó con un ejemplo real (Parte 1)
Tags TypeScript avanzó con un ejemplo real (Parte 1)
homefinance blog