He desarrollado varias aplicaciones de interfaz de usuario y, mientras las analizo, a menudo necesito refactorizar el código de interfaz de usuario o fallar la interfaz de usuario en el siguiente caso:
Supongamos que hay un punto final /movies que devuelve la siguiente respuesta:
{ "movieName": "Avengers Endgame", "genre": "Action, Thriller", "length": 120 // in minutes "rating": 4, "id": 1 } Para manejar la respuesta de este punto final en la aplicación frontend (React + Typescript), he creado un MovieType y renderizaré los datos en el componente.
// types.ts export type MovieType = { movieName: string; genre: string; length: number; rating: number; id: number; } import React from 'react'; function MovieComponent() { const [movies, setMovies] = React.useState([] as MovieType[]); React.useEffect(() => { const data:MovieType[] = fetchDataSomeHow() as MovieType[]; setMovies(data); }) return ( <ul> movies.map(movie => ( <li key={movie.id}> {movie.movieName.toLoweCase()} - {movie.rating} </li> )) </ul> ) } Así que aquí he creado MovieType observando la respuesta del punto final /movies y movieName como se requiere en MovieType . Aquí MovieType se ve afectado por los datos devueltos por el extremo /movies .
Como estoy usando Typescript y he definido movieName como string y required , puedo usar el método toLowerCase sin controles adicionales.
Ahora supongamos que hay alguna entrada incorrecta en la base de datos de películas y en la respuesta movieName es undefined/null o movieName se cambia a name . Ahora la aplicación frontend fallará debido a errores de tiempo de ejecución.
Esto sucede cada vez que hay una discrepancia en el contrato de la API en el frontend y el backend debido a entradas incorrectas en la base de datos o cambios repentinos en la API del backend.
¿Hay algún estándar o una buena manera de manejar este tipo de errores? Puedo fácilmente hacer que cada campo sea opcional y luego escribir el código de interfaz, pero será complicado y no se podrá leer. En el backend, tenemos conceptos de adaptadores que validan y desinfectan los datos y arrojan errores en caso de solicitudes no válidas, pero en el frontend, no podemos colgar a los usuarios en una página de error solo porque tenemos un campo incorrecto en un objeto. entre 1000 objetos.
Puede verificar si la película existe usando && check:
movie && {movie.movieName.toLoweCase()} - {movie.rating}Clasificaría el tipo como desconocido . Panorama general, estás recibiendo algo y no sabes lo que es. Entonces es desconocido. Después de hacer esto, TypeScript lo obligará a verificar todo, luego obtendrá todos los beneficios del resultado escrito.
Todavía podría definir el tipo
export type MovieType = { movieName: string; genre: string; length: number; rating: number; id: number; } Pero su resultado de la API inicialmente sería unknown . Después de obtener su resultado, reduciría el resultado. El tipo unknown lo protegerá de errores en este proceso. Cuando se reduce adecuadamente, puede asignarlo a un tipo de MovieType o trabajar con los de ese tipo.
const result: Record<string, unknown> = { movieName: "test", }; export type MovieType = { movieName: string; genre: string; length: number; rating: number; id: number; }; let someMovie: MovieType | undefined; if ( typeof result === "object" && typeof result.movieName === "string" && typeof result.genre === "string" && typeof result.length === "number" && typeof result.rating === "number" && typeof result.id === "number" ) { someMovie = { movieName: result.movieName, genre: result.genre, length: result.length, rating: result.rating, id: result.id, }; } Desafortunadamente, no pude usar directamente el tipo unknown y limitarlo hasta un Record<string, unknown> . Hice mi propia pregunta sobre esto, pero creo que puede ser imposible actualmente.