ProgramaciónDesarrollador Fullstack

¿Cómo funciona la tipificación de funciones asíncronas y Promise en TypeScript? ¿Cómo describir de forma segura los valores retornados, capturar errores de tipificación, cuál es la diferencia con las funciones normales? Proporcione ejemplos.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En TypeScript, las funciones asíncronas (async/await) siempre retornan un Promise. El tipo de valor retornado se especifica así: Promise<Type>. Al describir la función, es importante tipificar explícitamente el resultado para que TypeScript funcione correctamente con los tipos dentro de la promesa. Los errores de tipificación pueden surgir si los valores intermedios no coinciden con los que se declaran.

Función asíncrona:

async function fetchUser(id: number): Promise<User> { const response = await fetch(`/api/user/${id}`); const data: User = await response.json(); return data; }

Si la función debe retornar un error o rechazo, el tipo de promesa no debe describir el error directamente (Promise<Error>), ya que el rechazo de la promesa no se tipifica, sino que se captura a través de catch.

La tipificación de las cadenas de promesas es importante:

function getNumber(): Promise<number> { return Promise.resolve(42); } getNumber().then(val => val.toFixed(2)); // TypeScript sabe que val es un número

Pregunta capciosa.

Pregunta: ¿Puede una función asíncrona retornar algo diferente a una promesa?

Respuesta: No. Una función asíncrona siempre retorna un objeto Promise. Si se devuelve explícitamente un valor que no es una promesa, TypeScript envolverá automáticamente el valor retornado en una promesa.

async function test() { return 1; } const result = test(); type ResultType = typeof result; // Promise<number>

Ejemplos de errores reales por desconocer los matices del tema.


Historia

Un desarrollador escribió una función sin tipificar explícitamente el valor retornado, suponiendo que retornaba un objeto de un tipo específico. Al cambiar la lógica, la función empezó a retornar otro tipo, y esto no se notó de inmediato, ya que TypeScript, basándose en la inferencia de tipos, no generaba error. Finalmente, los errores se manifestaron solo en tiempo de ejecución, cuando el consumidor de la función intentó acceder a una propiedad inexistente.


Historia

En un proyecto, las cadenas de promesas no estaban tipificadas. Intentar acceder a un método inexistente en el resultado conducía a errores. Así, el resultado then(response => response.data) se consideraba any, y el error de captura de campos o métodos se manifestaba solo en tiempo de ejecución. El error pasó a producción y fue descubierto solo gracias a los usuarios.


Historia

Se declaró una función asíncrona con el tipo Promise<Error>, creyendo que esto permitiría capturar errores, pero en realidad los errores no se pasaban a través de throw y la promesa se rechazaba con otro tipo de valor. Esto llevó a una mezcla implícita de errores y valores válidos, causando fallos en la lógica de manejo de resultados de promesas.