Skip to Content
Course content

100: Typing Promises and Async Functions

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're at a busy deli. You order a custom sandwich, but the staff doesn't hand you the food immediately. Instead, they give you one of those little plastic buzzers. That buzzer isn't a sandwich—you can't eat it—but it is a promise that a sandwich will exist in the future. There are only two ways this ends: either the buzzer goes off and you get your sandwich (success), or the staff comes over and tells you they've run out of sourdough (failure).

Mapping the Deli to the Code

In TypeScript, a Promise<T> is exactly like that buzzer. The T represents the type of "sandwich" you're expecting back. If you're fetching a user profile from a database, you aren't getting the user immediately; you're getting a Promise<User>.

interface User {
  id: string;
  username: string;
  email: string;
}

// This function doesn't return a User. 
// It returns a "buzzer" that will eventually resolve into a User.
async function fetchUserProfile(userId: string): Promise<User> {
  const response = await fetch(`/api/users/${userId}`);
  return response.json(); 
}

Notice the Promise<User> return type. This tells anyone using this function, "Hey, you can't use the user data right this second, but I guarantee that whenever this finishes, you'll have a User object."

The async Shortcut

I've seen a lot of developers struggle with where to put the type when using the async keyword. Here is the golden rule: any function marked async must return a Promise. Even if you return a simple string, TypeScript wraps it in a Promise automatically.

// Even though I'm returning a string, the return type is Promise<string>
async function getWelcomeMessage(): Promise<string> {
  return "Welcome back to the app!";
}

If you try to set the return type as just string on an async function, TypeScript will throw an error. It's reminding you that asynchronous code doesn't happen instantly—it's always a "buzzer" situation.

When the "Sourdough" Runs Out

Now, what happens when the API call fails? In the deli analogy, this is the staff telling you they're out of bread. In TypeScript, this happens in the catch block. One quirk I want you to watch out for: TypeScript doesn't let you specify the type of a caught error. By default, the error is any or unknown.

Because a server could throw a 404, a 500, or a network timeout, TS can't possibly know exactly what the error object looks like. I usually handle this with a type guard or a simple cast if I'm certain of the error shape.

async function loadDashboard() {
  try {
    const user = await fetchUserProfile('123');
    console.log(user.username);
  } catch (err) {
    // 'err' is unknown. We have to be careful here.
    if (err instanceof Error) {
      console.error("Failed to load: " + err.message);
    } else {
      console.error("An unexpected error occurred");
    }
  }
}

I highly recommend using instanceof Error. It's the cleanest way to tell TypeScript, "I've checked, and this is a standard JavaScript Error object," allowing you to access .message without the compiler complaining.




📋 Practical Task

Implementing a GitHub Repo Stats Fetcher

Your goal is to create a type-safe function that fetches public repository data from the GitHub API. You'll need to define the shape of the API response and ensure the async function is typed correctly.

Requirements:

  • Define an interface RepoStats with name (string), stargazers_count (number), and forks_count (number).
  • Write an async function called getRepoStats that takes a repoName (string) and returns a Promise<RepoStats>.
  • Use fetch() to get the data from https://api.github.com/repos/[repoName].
  • Implement a try/catch block that handles potential errors using an instanceof Error check.
// Start your code here:
interface RepoStats {
  // ...
}

async function getRepoStats(repoName: string): Promise<RepoStats> {
  // ...
}
Rating
0 0

There are no comments for now.

to be the first to leave a comment.