Skip to Content
Course content

229: Specifying void as a Return Type

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

I've seen this happen to a lot of developers when they're moving from JavaScript to TypeScript. You write a function that's meant to perform a "side effect"—like logging a message, updating a global variable, or saving something to a database—and you just let TypeScript infer the return type. It feels fine until someone else (or you, three months from now) tries to use the result of that function.

The danger of the implicit return

function trackAnalyticsEvent(eventName: string, metadata: object) {
    console.log(`Sending ${eventName} to server...`, metadata);
    // Imagine a fetch call happens here
}

const response = trackAnalyticsEvent("button_click", { id: "submit-btn" });

if (response) {
    console.log("Event tracked successfully!");
}

At first glance, this looks okay. But look closely at that if (response) block. Since trackAnalyticsEvent doesn't have a return statement, TypeScript infers its return type as void. In JavaScript, a function that doesn't return anything actually returns undefined.

The bug here is a logic error: the developer thinks trackAnalyticsEvent is returning a success boolean or a response object, but it's actually returning undefined. Because undefined is falsy, the "success" block will never execute, and you'll be scratching your head wondering why your analytics tracking isn't "working," even though the event is actually being sent.

Hardening the contract with void

To fix this, we don't change the logic—we change the contract. By explicitly specifying : void, you are telling every other developer on the team: "This function performs an action, but it provides no data back. Do not try to use its return value for anything."

function trackAnalyticsEvent(eventName: string, metadata: object): void {
    console.log(`Sending ${eventName} to server...`, metadata);
}

const response = trackAnalyticsEvent("button_click", { id: "submit-btn" });

// TypeScript now throws a compile-time error here:
// "The left hand side of an 'if' condition should be an expression of type 'boolean'."
if (response) { 
    console.log("Event tracked successfully!");
}

Now, the bug is caught before the code ever runs. TypeScript sees that response is of type void and warns you that checking a void value in a conditional is nonsense. If you actually needed to know if the event was tracked, this error forces you to rethink the function signature—perhaps changing it to return a Promise<boolean>.

I'll be honest: some people argue that explicit void is redundant because TS infers it anyway. I disagree. In a professional codebase, explicit types act as documentation. When I see : void, I know the author intentionally designed it to return nothing, rather than just forgetting to write a return statement.

  • Use void when the function's only purpose is to change something outside its own scope (a side effect).
  • Avoid using void if you might eventually need to return a status code or a success flag.
  • Remember that void is different from never; void means "returns nothing," while never means "this function never actually finishes" (like a function that always throws an error).



📋 Practical Task

Fixing the User Notification Dispatcher

You are working on a notification system. One of the functions, notifyUser, is designed to simply trigger a UI alert. However, a teammate has tried to use it inside a loop to track how many notifications were "successfully" sent, leading to a bug where the counter never increments.

Your Task:

  • Modify the notifyUser function to explicitly specify void as its return type.
  • Identify and remove the broken logic that attempts to use the return value of notifyUser.
  • Ensure the code compiles without errors.
interface User {
    id: string;
    name: string;
}

function notifyUser(user: User, message: string) {
    console.log(`Notification sent to ${user.name}: ${message}`);
}

const users: User[] = [
    { id: "1", name: "Alice" },
    { id: "2", name: "Bob" }
];

let notificationCount = 0;

users.forEach(user => {
    const result = notifyUser(user, "Welcome to the platform!");
    if (result) {
        notificationCount++;
    }
});

console.log(`Total notifications sent: ${notificationCount}`);
Rating
0 0

There are no comments for now.

to be the first to leave a comment.