async/await cu tipuri în TypeScript

Cod asincron și iterare TypeScript 1.7

O funcție async returnează mereu Promise<T>; await scoate valoarea de tip T din Promise.

Sintaxă
async function f(): Promise<Tip> {
    const x = await altaFunctie();
    return valoare;
}
const g = async (a: number): Promise<string> => { ... };

Ce face async/await cu tipuri

O funcție marcată async returnează întotdeauna un Promise. Dacă în corp faci return 5, tipul funcției este Promise<number>. Tipul scris explicit trebuie să fie Promise<...>; async function f(): number este eroare.

await așteaptă un Promise și îți dă valoarea din el, cu tipul corect: await citesteNote(), unde funcția returnează Promise<number[]>, are tipul number[]. În fișierele modul (.mts, ESM) poți folosi await direct la nivelul de sus, în afara oricărei funcții.

Erorile aruncate într-o funcție async devin Promise-uri respinse și se prind cu try/catch în jurul lui await; în modul strict, variabila din catch are tipul unknown. Pentru funcții asincrone fără rezultat, tipul este Promise<void>.

Exemple

Exemplul 1: Citirea unui fișier cu await

import { readFile, writeFile } from "node:fs/promises";

interface Elev {
    nume: string;
    nota: number;
}

async function salveaza(elevi: Elev[]): Promise<void> {
    await writeFile("elevi.json", JSON.stringify(elevi));
}

async function citeste(): Promise<Elev[]> {
    const text = await readFile("elevi.json", "utf8");    // string
    return JSON.parse(text) as Elev[];
}

await salveaza([{ nume: "Ana", nota: 10 }, { nume: "Mihai", nota: 8 }]);
const elevi = await citeste();
console.log(elevi.map((e) => `${e.nume}=${e.nota}`).join(", "));

Rezultat

Ana=10, Mihai=8

Exemplul 2: Erori cu try/catch

import { readFile } from "node:fs/promises";

async function citesteSau(fisier: string, implicit: string): Promise<string> {
    try {
        return await readFile(fisier, "utf8");
    } catch (e) {
        if (e instanceof Error && "code" in e) console.log(`Nu pot citi ${fisier}: ${e.code}`);
        return implicit;
    }
}

console.log(await citesteSau("nu-exista.txt", "(gol)"));

Rezultat

Nu pot citi nu-exista.txt: ENOENT
(gol)

Exemplul 3: Tipul rezultatului trebuie să fie Promise

async function nota(): number {
    return 10;
}
console.log(await nota());

Eroarea afișată de tsc

exemplu.mts(1,24): error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<number>'?

Greșeli frecvente

  • Uiți await în fața unei funcții async: primești un Promise în loc de valoare, iar o eventuală eroare nu mai este prinsă de try/catch.
  • Folosești await în bucle unde operațiile sunt independente. Rulează-le în paralel cu Promise.all.
  • Scrii return readFile(...) fără await într-un try. Dacă Promise-ul este respins, catch-ul din funcție nu îl prinde; scrie return await.

Comenzi înrudite

  • Promise<T>: Tipul unei valori care va fi disponibilă mai târziu; T este tipul rezultatului, nu și al erorii.
  • Awaited: Awaited<T> dă tipul valorii pe care o obții cu await din T, desfăcând și Promise-urile imbricate.
  • void: Tipul returnat de funcțiile care nu întorc nicio valoare utilă, de exemplu cele care doar afișează ceva.
  • unknown: Tipul sigur pentru valori necunoscute: acceptă orice, dar nu poți folosi valoarea până nu verifici ce tip are.
  • tipuri pentru Node.js: Tipurile pentru modulele Node.js (fs, path, process…) vin din pachetul @types/node.