Cómo tipar componentes en React  con TypeScript

Curso de React.js con TypeScript

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

¡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).

¿Cómo usar TypeScript en React?

Existen un par de formas de empezar o agregar TS a un proyecto de React:

  • 1️⃣ Creando tu proyecto con npx
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

  • 2️⃣ Agregando TS a un proyecto ya existente

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

TypeScript en acción

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

Elementos de la card

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

Construyendo componentes con TS

Una vez tengas todo el setup de tu proyecto, empieza creando el componente Course.jsx, el cual tendrá la siguiente estructura:

// src/components/Course.jsx

export const 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.tsx

type Teacher = {
  name: string,
  img?: string,
}

type CourseProps = {
  img: string,
  name: number,
  classes?: number,
  date: Date,
  teacher: Teacher,
  level: string,
  addToFavorite: MouseEventHandler,
  addToPath: MouseEventHandler
}

export const 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:

Card course react ts

💻 Aquí en el codepen está el código completo
📖 Repositorio de Github con el código completo

Cómo dominar TypeScript

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 😉

Curso de React.js con TypeScript

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

0 Comentarios

para escribir tu comentario

Artículos relacionados