Blog ✌️
TypeScript con React para mejorar la experiencia de los desarrolladores
Publicado el
Esta entrada del blog echa un vistazo a cómo podemos utilizar TypeScript para mejorar nuestros proyectos con React.
Si eres un desarrollador de React.js y no usas TypeScript, ¡este artículo es para ti!
🔌 Los Props son un medio de contacto
La característica central de React son los componentes. Nos ayuda a tener una verdadera separación de conceptos. Necesitamos muchos de ellos para construir una UI completa, así que tenemos que hacerlos interactuar.
La forma sencilla de mover datos de una componente a otro es a través de props:
import React from 'react'
import Post from './Post'
export default function SinglePost({ post }) {
return (
<>
<Post title={post.title} description={post.description} />
</>
)
}
Es un patrón típico: un componente obtiene información de props, utiliza otros componentes y les proporciona props. El component SinglePost
aquí utiliza el componente Post
. Para proporcionar información desde SinglePost
a Post
, utilizamos props. Es un medio de comunicación, y debe ser visto como tal por los desarrolladores.
¿Qué es entonces un medio de contacto perfecto? No es tanto la capacidad de conectar, sino las características de UX que la rodean.
Para hablar con algunos amigos, utilizo WhatsApp. Puedo enviar y recibir mensajes, por supuesto, pero ¿cuáles son las características que tenemos alrededor de eso? Para saber si mi mensaje ha sido leído, he visto el check azul, genial. No tengo posibilidad de editar mi mensaje, no me gusta para nada (viva Telegram). ¿Qué pasa con los props de React? Puedes asignar un valor a un componente, vale, pero ¿qué experiencia de desarrollador tenemos alrededor de esto? Type check
Los types pueden fortalecer la DX (Developer Experience), ya que cuando algo está mal, puede alertarnos. El uso de prop-types es la forma normal de añadir type check a nuestros props.
import React from "react";
import PropTypes from "prop-types";
const Post = ({ title, description = "" }) => {
return (
<div className="px-6 py-2 rounded shadow-sm">
<h2 className="text-2xl font-bold">{title}</h2>
{description && (
<p className="text-sm">{description}</p>
)}
</div>
);
};
Post.propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.string
};
export default Post
Genial, podemos comunicarnos más eficientemente, ya que podemos decidir si una prop es requerida o no, si es una cadena u otro tipo, ¡o incluso dar una lista estricta de valores posibles! En nuestro caso, cuando queremos ver nuestro Post, y no le pasamos un título, esto es lo que nos dice el navegador:
¡Perfecto! Buena captura PropTypes, ¡gracias! Imagínate ahora que podemos tomar esta definición de los tipos de pruebas adicionales y la comprobación de todo nuestro código aún más allá 🚀
😎 TypeScript entra a la acción
La librería prop-types estaba incluida en React antes de React v15.5. El equipo de React tomó la opción de extraerla del core, fiel a su ideología de proporcionar una librería impopular, para permitir a los desarrolladores utilizar otros sistemas de tipado, como Flow o TypeScript. Esto último, vamos a probarlo.
Uno de los obstáculos de entrada de TypeScript es que la herramienta tiene que ser construida y configurada antes de que puedas usarla. No es tan fácil como yarn add prop-types
, sin duda. En mi opinión, la mejor manera de aprender TypeScript es saltarse completamente este paso. Simplemente construye con CRA una nueva aplicación React, ¡y empecemos a aprender!
yarn create react-app my-project --template typescript
Creado. Ahora, en nuestro componente de <Post />
, vamos a cambiar de PropTypes a TypeScript.
import * as React from "react";
interface Props {
title: string
description?: string
}
const Post = ({ title, description = "" }: Props): JSX.Element => {
return (
<div className="px-6 py-2 rounded shadow-sm">
<h2 className="text-2xl font-bold">{title}</h2>
{description && (
<p className="text-sm">{description}</p>
)}
</div>
);
};
export default Post
La magia de TypeScript es que los type
e interfaces
que tenemos no sólo están disponibles exclusivamente. Para deducir el conocimiento, también analiza nuestro código.
TypeScript también viene con un pequeño extra: puede hacerlo justo en el editor de código cuando estás desarrollando. Para obtener pistas de una función, no tienes que esperar a que se ejecuten en el navegador, como ocurría con los prop-types.
Esto es lo que muestra mi VSCode con una función que tengo para verificar el tiempo de lectura de un texto:
Ahora que estamos en esto, cambiemos también nuestro <SinglePost />
component:
import * as React from 'react'
import Post from './Post'
interface Props {
post: {
title: string
description?: string
}
}
export default function SinglePost({ post }: Props) {
return (
<>
<Post title={post.title} description={post.description} />
</>
)
}
Pero, ¿qué pasa cuando queremos recibir un string que solo puede ser small
, medium
o large
por ejemplo para el tamaño de la foto del post? Pues veamos el siguiente código y cómo actua TypeScript con la validación:
import * as React from 'react'
import Post from './Post'
interface Props {
post: {
title: string
description?: string
imageSize: "small" | "medium" | "large"
}
}
export default function SinglePost({ post }: Props): JSX.Element {
return (
<>
<Post title={post.title} description={post.description} />
</>
)
}
import * as React from 'react'
interface Props {
title: string
description?: string
imageSize: 'small' | 'medium' | 'large'
}
const Post = ({ title, description = '', imageSize }: Props): JSX.Element => {
return (
<div className="px-6 py-2 rounded shadow-sm">
<h2 className="text-2xl font-bold">{title}</h2>
{description && <p className="text-sm">{description}</p>}
<img src="https://picsum.photos/200/300" alt={title} className={imageSize} />
</div>
)
}
export default Post
Ahora si pasamos el mouse por encima de nuestro código donde está el componente <Post />
en single-post.tsx
veremos el siguiente error:
Al agregar la nueva prop y abrir las comillas nos daremos cuenta que TypeScript ahora nos está autocompletando los size posibles que se le puede pasar y adicionalmente nos dice que debemos pasarle el prop correcto porque de otra forma no corresponde con los types que se declararon:
Asombroso, ¿no lo crees? 😎
Y lo que es realmente genial es que TypeScript no está restringido a las partes props, a diferencia de PropTypes. Todo nuestro código JavaScript, incluso lo que no está conectado a nuestros componentes React, puede tener alertas. Incluso lo que no está totalmente conectado al front-end, ya que TypeScript funciona con NodeJS de mil maravillas.
Ahora, en nuestro código, podemos estar seguros.
TypeScript estará ahí para gritarnos si hay una discrepancia en algún lugar, señalando el fallo que estaba delante de nuestras narices, pero que de alguna manera pasamos por alto.
🧐 Conclusiones
No voy a mentir, el camino no es fácil con TypeScript y a veces la curva de aprendizaje puede ser dura. Pero sin duda vale la pena, supongo (?) 😂
Al proponer una herramienta de código abierto que es sensible a los avances de JavaScript, Microsoft ha hecho un gran trabajo. Este nuevo cuasi-estándar ha sido acogido por el ecosistema JS, y muchas librerías son compatibles con TypeScript para permitirnos hacer nuestro código, como hicimos en nuestros ejemplos con el JSX.Element
de React.
Fue una apuesta a mí mismo poder entrar a TypeScript hace algún tiempo, y siempre perdía. ¿Ahora en 2021? Es una apuesta bastante obvia. Hoy, ¡úsalo! No te arrepentirás.
Oh y si me había olvidado comentarte JSX.Element
es una forma de decirle a TypeScript que lo que retorna esa función es JSX y no necesita hacer nada más, en posteriores post que iré sacando sobre aprendiendo TypeScript con React explicaré para que sirve FunctionalComponent
y JSX.Element
en nuestro código.
- Los veo en el código 👨💻