Saltar al contenido

Cómo usar el React Router en la tipografía

Introducción

Citando a Wikipedia:

Nos permite especificar exactamente cuál es la forma de nuestro objeto y qué tipo de parámetro esperamos recibir en una función, añadiendo así una capa de seguridad al código que escribimos.

Cómo usar el React Router en la tipografía
Cómo usar el React Router en la tipografía

Para añadir TypeScript a un proyecto de Create React App, primero instálalo:

1npminstall --save-dev typescript @types/node @types/react @types/react-dom @types/jest @types/react-router-dom

bash

A continuación, renombre cualquier archivo para que sea un archivo TypeScript (por ejemplo, src/index.js a src/index.tsx) y reinicie su servidor de desarrollo !

Inmediatamente después de que el servidor de desarrollo se inicie obtendrás un error:

123456789101112He fallado al error de compilación.C:/temp/demo-app/src/App.tsxType: El elemento vinculante "matches" implícitamente tiene un tipo "any". TS7031 6||7||;8|función Producto({cordes }){| ^ 9|retorno<h2|;Esta es una página para producto con ID: {coches.params.id}</h2;};10|}11|||/pre>
bash

¡Maravilloso! Nuestro error de imprenta ha sido detectado. Ahora, veamos cómo resolver el problema.

Añadir tipos

Antes de empezar, quiero llamar su atención sobre el comando de instalación npm que hemos ejecutado antes. Además de añadir el compilador de Typescript, también hemos instalado varios paquetes @types. ¿Cuáles son? Cada paquete @types contiene en su interior varios archivos .d.ts que proporcionan la información de tipo real para las librerías instaladas desde el NPM.

Por ejemplo, cuando usas una biblioteca de cadenas de consulta popular en tu código:

12345678const queryString =require($0027query-string$0027);console.log(location.search);//=> $0027?foo=bar$0027const parsed = queryString.parse(location.search);console.log(parsed);//=> {foo: $0027bar$0027}

javascript

El compilador de Typescript no tiene forma de saber si el parámetro que pasó al método queryString.parse es el tipo correcto. Puedes llamar a queryString.parse(123) que será un código válido, pero se bloqueará al ejecutarse porque la función espera obtener una cadena para el análisis sintáctico.

Para mitigar este problema, existe un paquete separado que contiene las definiciones de los tipos y que puede instalarse junto al paquete principal para aumentarlo:

1npminstall --save-dev @tipos/cadena de consulta

bash

Este paquete contiene un archivo index.d.ts con el siguiente código:

1exportfunctionparse(str:string, options?:ParseOptions):OutputParams;

tipografía

Le dice al compilador: Tengo una función de análisis que acepta hasta dos parámetros. El primero es un parámetro obligatorio de tipo cadena y el segundo parámetro opcional se llama opciones. ¡Ahora, llamando a queryString.parse con cualquier cosa menos una cadena te dará un error de sintaxis!

Ahora que nos hemos familiarizado con los fundamentos del uso de los paquetes de tipos, vamos a anotar nuestro código para describir qué parámetros esperamos y cómo los manejamos. Empezaremos por mirar más de cerca el componente sin estado del producto:

123funciónProducto({cordar }){retorno<h2};Esta es una página de producto conID:{cordar.params.id}</h2};}

javascript

Cada componente sin estado en React se define como una función que recibe sus puntales y devuelve un elemento de React. En nuestro caso, usamos JSX para generar ese elemento y usamos la sintaxis de propagación para agarrar el puntal de fósforo. ¿Cómo supimos que los accesorios contienen el objeto de fósforo? Bueno, hemos leído la documentación. En el mundo de Typescript, tenemos una forma mejor. Podemos inspeccionar el paquete @types y aprender sobre los tipos reales de los parámetros como React Router espera verlos.

Abramos el archivo node_modules/@types/react-router/index.d.ts y busquemos la definición de la Ruta:

1234567891011121314151617exporterfaceRouteComponentProps<Paramsextends{[KinkeyofParams]?:string}={},CextendsStaticContext=Contexto Estático,S=H.LocationState,S=H.LocationState,{ history:H.History;location:H. Location<S¿;; match: match<Params¿;; staticContext?:C;}exporterfaceRouteProps{localización?:H.Location; component?:React.ComponentType<RouteComponentProps<any ComponentType<any>; render?:((props:RouteComponentProps<any>)=;React.ReactNode); children?:((props:RouteChildrenProps<any>)=;React.ReactNode)|React. ReactNode; path?:string|string[]; exact?:boolean; sensitive?:boolean; strict?:boolean;}exportclassRoute<TextendsRouteProps=RouteProps;|extendeReact.Component<T,any
tipografía

Vemos que una ruta es un componente de reacción que recibe puntales en forma de puntales de ruta. Luego hace que el componente que le proporciona el componente de puntales y define qué puntales pasará a ese componente: RutaComponenteAtrezzo.

Cuando inspeccionamos la Ruta-Propósito, vemos que contiene toda la información que esperamos que tenga una Ruta: ubicación, historia y el propulsor del fósforo.

Volvamos a nuestro código y traigamos el tipo RouteComponentProps y apliquémoslo a nuestro parámetro de función de Producto.

Empezamos importando el tipo del paquete react-router-dom:

123456import{BrowserRouterasRouter,Route,Link,RouteComponentProps}de "react-router-dom";

tipografía

y luego anotando nuestro parámetro de función:

12345tipoTParams={ id:número};funciónProducto({cordancia }:RutaComponentePropósitos<TParams;}} {retorno<h2;Esta es una página para producto conID:{cordancia.params.id}</h2;}

tipografía

Básicamente le "explicamos" al compilador que:

  1. La función recibe un parámetro.
  2. El parámetro es del tipo RouteComponentProps.
  3. El contenido del campo de fósforos dentro de los puntales será del tipo TParams.
  4. TParams se define como un objeto que tiene un campo de identificación de tipo número. Todo hecho, ¿verdad? No exactamente. Nuestro servidor de desarrollo está dando un error:
1234567891011Error de tipo: El tipo $0027TParams$0027 no satisface la restricción $0027{ id?: cadena | indefinida; }$0027. Los tipos de propiedad $0027id$0027 son incompatibles. El tipo $0027number$0027 no es asignable al tipo$0027string | undefined$0027. TS2344 13|tipo TParams ={ id: número };14|||;15|función Producto({ match }: RouteComponentProps<TParams;){| ^ 16|devolución<h2|;Esta es una página para el producto con ID: {match.params.id}</h2;};17|||18|

bash

¡Ajá! Pensamos que como esperamos que la identificación sea un número, podemos declararla como tal. Pero el compilador nos advierte - El tipo $0027número$0027 no es asignable al tipo $0027cadena | indefinida$0027 . Significado: cuando React Router analiza los parámetros de ruta, no hace ninguna conversión de tipo, ni tiene ninguna forma de saber cuál es el tipo real de parámetro id, por lo que lo declara como string | undefined.

Arreglemos nuestra definición de TParams para que coincida:

1typeTParams={ id:string};

tipografía

Voilà, el código compila y tenemos la tranquilidad de saber que la próxima vez intentaremos hacer algo inesperado mientras pasamos los parámetros de enrutamiento - el compilador estará de nuestro lado y nos avisará de inmediato!