ProgrammazioneSviluppatore Fullstack

Come funziona la tipizzazione delle funzioni asincrone e dei Promise in TypeScript? Come descrivere in sicurezza i valori di ritorno, catturare gli errori di tipizzazione, qual è la differenza rispetto alle funzioni normali? Fornisci esempi.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In TypeScript, le funzioni asincrone (async/await) restituiscono sempre un Promise. Il tipo del valore di ritorno si specifica come Promise<Type>. Quando si descrive una funzione, è importante tipizzare esplicitamente il risultato affinché TypeScript lavori correttamente con i tipi all'interno del promise. Gli errori di tipizzazione possono verificarsi se i valori intermedi non coincidono con quelli dichiarati.

Funzione asincrona:

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

Se la funzione deve restituire un errore o un rifiuto, il tipo di promise non dovrebbe descrivere l'errore direttamente (Promise<Error>), poiché il rifiuto del promise non è tipizzato e viene catturato tramite catch.

La tipizzazione delle catene di promise è importante:

function getNumber(): Promise<number> { return Promise.resolve(42); } getNumber().then(val => val.toFixed(2)); // TypeScript sa che val è un numero

Domanda insidiosa.

Domanda: Una funzione asincrona può restituire qualcosa oltre a un promise?

Risposta: No. Una funzione asincrona restituisce sempre un oggetto Promise. Se si restituisce esplicitamente un valore non-promise, TypeScript avvolgerà automaticamente il valore restituito in un promise.

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

Esempi di errori reali dovuti a una scarsa comprensione dei dettagli del tema.


Storia

Uno sviluppatore ha scritto una funzione senza una chiara tipizzazione del valore di ritorno, assumendo che restituisse un oggetto di un certo tipo. Cambiando la logica, la funzione ha iniziato a restituire un altro tipo, e questo non è stato notato subito, poiché TypeScript, basandosi sull'inferenza di tipo, non ha generato errori. Alla fine, gli errori si sono manifestati solo a runtime, quando il consumatore della funzione ha tentato di chiamare una proprietà inesistente.


Storia

In un progetto, le catene di promise non erano tipizzate. Il tentativo di accedere a un metodo inesistente sul risultato ha portato a errori. Così, il risultato then(response => response.data) era considerato any, e l'errore di cattura di campi o metodi si è manifestato solo a runtime. L'errore è andato in produzione ed è stato scoperto solo grazie agli utenti.


Storia

Una funzione asincrona è stata dichiarata con il tipo Promise<Error>, pensando che questo avrebbe permesso di catturare gli errori, ma in realtà gli errori non venivano propagati tramite throw e il promise veniva rifiutato con un altro tipo di valore. Questo ha portato a una mescolanza implicita di errori e valori validi, e alla comparsa di bug nella logica di gestione dei risultati dei promise.