¡Empieza a tipar tus componentes de React con TypeScript!
Ya te hablé un poco del porqué es una gran idea empezar a tipar tus componentes con PropTypes y algunas de sus ventajas a la hora de desarrollar con ellos. Ahora es el turno de una de sus alternativas: TypeScript.
TypeScript no es un lenguaje nuevo, sino un superset de JavaScript, el cual le da superpoderes para que se vuelva un lenguaje fuertemente tipado.
Cuando combinas el poder de React con el de TypeScript obtienes una excelente dupla para desarrollar aplicaciones web con las mejores prácticas. Esto gracias a que ahora tus proyectos proyectos serán auto descriptivos desde un inicio (siempre y cuando elabores un buen tipado dentro de tus componentes).
Existen un par de formas de empezar o agregar TS a un proyecto de React:
npx create-react-app my-app --template typescript
💡 El flag --template prepara todo un ambiente para que desarrolles con TS y React desde 0, te recomiendo usarlo en proyectos pequeños
Si ya tienes un proyecto inicializado con webpack y quieres agregar TS, solo debes instalarlo con NPM o Yarn,junto con su loader como dependencia de desarrollo:
# NPM
npm install --save-dev typescript ts-loader`
# Yarn
yarn add typescript ts-loader --dev
Después de esto procedes a añadirlo en Webpack y lo configuras de la siguiente forma:
```js
// webpack.config.js
const path = require("path");
module.exports = {
entry:"./src/index.js",
module: {
// Agregas como regla usar el loader de typescript rules: [
...{
test: /\.tsx?$/,
use:"ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
// Al usar ts para tu proyecto debes agregar las extensiones// .ts y .tsx dentro del array de extensiones extensions: [".tsx", ".ts", ".js"],
},
output: {
filename:"bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
Aunque esto no será suficiente para que puedas empezar a desarrollar con TS, ya que también necesitas un archivo de configuración llamado tsconfig.json
:
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"allowJs": true,
"moduleResolution": "node"
}
}
💡 Puedes seguir el paso a paso de una manera más fluida en esta clase del curso práctico de webpack
En otra entrada ya vimos como funcionan las Proptypes recreando un componente del blog de Platzi. Ahora vas a construir la vista de la card de los nuevos curso (aunque vamos a customizarla un poco para darle un toque especial).
💡 Para efectos prácticos del ejemplo puedes usar npx create-react-app --template typescript
Antes de entrar de lleno al código, debes ver que props necesitará el componente y para ello puedes analizarlo visualmente, aquí abajo lograrás ver de manera más clara los elementos 👇🏻
Prop | Type |
---|---|
img | string |
name | string |
date | Date |
teacher | Teacher |
level | string |
rating | number |
classes | number |
addToPath | MouseEventHandler |
addToFavorites | MouseEventHandler |
Como te mencioné antes, vas a agregar algunos features a la card para hacerla más interesante y así poder experimentar un poco más con TypeScript . Para no extendernos tanto, te explico brevemente que el prop de teacher va a ser un tipo que definirás, ya que este va a tener internamente otras 2 propiedades: name y img
Por otro lado, las últimas dos funciones tienen que ser de un tipo que viene por defecto en React, llamado MouseEventHandler; el cual, como su nombre lo indica, desempeña su función para tipar todo manejador de eventos desencadenados por el mouse.
En la documentación oficial puedes encontrar más información sobre más de ellos
Una vez tengas todo el setup de tu proyecto, empieza creando el componente Course.jsx
, el cual tendrá la siguiente estructura:
// src/components/Course.jsxexportconst Course = ({
img,
name,
date,
teacher,
rating,
classes,
level,
addToFavorite,
addToPath,
}: {
// Una de las formas de tipar las props una por una es dentro de un objeto separado// por dos puntos
img: string,
name: string,
date?: Date,
// Los parámetros opcionales como date deben tener un ? antes de los dos puntos// al no tener el signo de interrogación TS los toma como parámetros obligatorios
teacher: { name: string, img?: string },
// Se puede definir la estructura de los objetos con el tipado de esta forma
rating: number,
classes: number | string,
// Cuando una prop puede ser de dos o más tipos usa el operador | (or) para especificarlos
level: string,
addToFavorite: MouseEventHandler,
addToPath: MouseEventHandler,
// Los event handlers tienen un tipo especial dentro de React
}) => {
return (
<div className="course">
<div className="course--body">
<div className="course-img">
<img src={img} alt={name} />
</div>
<div className="course-name">
<p>{name}</p>
</div>
<div className="course-teacher">
<p>Por {teacher.name}</p>
<div className="teacher-img">
<img src={teacher.img} alt={teacher.name} />
</div>
</div>
</div>
<div className="course--footer">
<div className="course--details">
<div className="course-classes-level">
<span className="course-classes">{classes} clases</span>
<span className="course-level">Nivel {level}</span>
</div>
<div className="course-year-rating">
<span className="course-rating">{"⭐".repeat(rating)}</span>
<span className="course-year">{date?.getFullYear()}</span>
</div>
</div>
<div className="course--buttons">
<button className="button-blue" onClick={addToPath}>
+ Agregar a mis rutas
</button>
<button className="button-yellow" onClick={addToFavorite}>
⭐ Favorito
</button>
</div>
</div>
</div>
);
};
// Esta es la estructura que utilicé, al menos para que tuviera una buena vista la card
⚠️ Cuando pasas una prop diferente a la esperada u omites el asignar una prop que no es opcional, puede hacer que tu App no compile y te muestre un error, especificándote el lugar que causa la detención de la misma
Una recomendación que te doy es que cuando tengas muchas props (como en este caso) prefieras hacer tus propios tipos, de la siguiente forma:
// src/components/Course.tsxtype Teacher = {
name: string,
img?: string,
}
type CourseProps = {
img: string,
name: number,
classes?: number,
date: Date,
teacher: Teacher,
level: string,
addToFavorite: MouseEventHandler,
addToPath: MouseEventHandler
}
exportconst Course = ({
img,
name,
date,
teacher,
rating,
classes,
level,
addToFavorite,
addToPath } : CourseProps ) => {...}
Puedes optar por usar interface o type, pero depende de ti siempre elegir la mejor opción, en esta clase puedes encontrar el uso de las interfaces
Ya con los estilos aplicados, así quedará la card con TS:
💻 Aquí en el codepen está el código completo
📖 Repositorio de Github con el código completo
Es bien sabido que JavaScript tiene unas características un tanto curiosas y puede hacer que tus aplicaciones lleguen a tener errores por olvidar hacer las validaciones correctas con sus tipos, aquí es donde TS viene a salvar el día disminuyendo estos y más problemas.
No te agobies por no saber por donde empezar, aquí abajo te dejo una serie de cursos para que aprendas a utilizar TS en proyectos reales y pienses en pasarte al lado azul 😉
¿Habrá curso de React con TypeScript? 👀
El Curso Práctico de Webpack integra TS y la saga de cursos de Next JS se manejan proyectos con React y TS 😄
Si lo quieren, yes, why not 💪
Siiii, por favor.
Estaría increíble!
incredible nice post