Is your async function lacking a return statement?

After completing the development of a new method for a bug I encountered, I noticed something interesting. Despite the fact that there is a potential scenario where the function may not return anything, the compiler did not flag any errors. It got me thinking - why does the compiler stay silent in this case, but raises an issue when using if (false)?

I'm particularly curious about what happens if the condition

if (data && data.json().length)
evaluates to false. Does the function still return a value under such circumstances?

private async getData(items: any[]): Promise<number> {
    for(const item of items) {
        let data = await item.promise;
        if (data && data.json().length) {
            return data.json().findIndex(d => d.fqdn);
        }
    }
}

Your insights would be greatly appreciated.

Answer №1

The TypeScript spec Section 6.3 provides insight into this topic (emphasis added):

An explicitly typed function with a return type that isn't Void, Any, or a union type containing Void or Any must have at least one reachable return statement in its body. An exception is made if the function consists of only a 'throw' statement.

Your function meets this requirement by having a reachable return statement. Placing the return inside an if (false) clause makes it unreachable and doesn't count towards this rule.

If the function exits without a clear return, it implicitly returns a promise for undefined, which is acceptable for Promise<number> when strictNullChecks is off.

This is separate from using async. The following scenarios will compile without errors:

function getData(): number { 
    if (1 + 1 === 3) {
        return 7;
    }
}

As well as:

function getData(): number { 
    if (1 + 1 === 3) {
        return undefined;
    }
}

What occurs if if (data && data.json().length) is false? Does the function return anything?

In such cases, the function returns a promise resolving to undefined since it's flagged as async, leading to promises being returned instead.

Note that when strictNullChecks is enabled, both your function and those mentioned may throw compiler errors due to the invalid use of undefined with number.

Answer №2

Asynchronous functions always result in a promise being returned. If the TypeScript compiler encounters an if (false) statement, it will raise an error because the following return statement is unreachable. In such cases, the function will return a promise containing undefined. A similar issue arises if

data && data.json().length
evaluates to false, but the compiler does not catch this problem.

If a function lacks a default value to return, there is no need for an explicit return statement at the end of the function. However, the function should be appropriately typed:

private async fetchData(results: any[]): Promise<number|void> {
    for(const result of results) {
        let data = await result.promise;
        if (data && data.json().length) {
            return data.json().findIndex(d => d.fqdn);
        }
    }
}

Answer №3

Every time the function is called, it will consistently output a Promise. If the function happens to return implicitly, the Promise will resolve to undefined.

If you have strictNullChecks turned on, this situation should trigger a compiler error.

To observe this, check out the TypeScript playground (and experiment with enabling/disabling strictNullChecks):

async function a(i: boolean): Promise<number> {
    if (i) return 5;
}

If you remove the async keyword and change the return type to number, you'll notice that the behavior remains the same.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular 5 is throwing an error stating that it cannot read the property 'text' of undefined

I have developed a question component where I have added some predefined questions. However, when I attempt to execute the application, it displays 'undefined' text. Below is my component code: import { Component, OnInit } from '@angular/c ...

Issue TS2322: The type 'Observable<any>' cannot be matched with type 'NgIterable<any> | null | undefined'

Encountering an error while attempting to fetch data from the API. See the error image here. export class UserService { baseurl: string = "https://jsonplaceholder.typicode.com/"; constructor(private http: HttpClient) { } listUsers(){ //this ...

Error 404 when implementing routing in Angular 2 with Auth0

In my Angular 2 application, I am utilizing Auth0 authentication. While everything works fine on localhost, I encounter issues when running the application on the server (my domain). Based on what I know, my problem seems to be with the routes. Iss ...

Setting Angular FormControl value to null within a service

My Angular form is reactive and collects mobile numbers along with other details. Here is the code snippet: component.html <form [formGroup]="contactDetailsForm"> <ngx-intl-tel-input [cssClass]="'ngxIntlInputBorder'&quo ...

The Nestjs ClientMqtt now has the capability to publish both pattern and data to the broker, as opposed to just sending

I am currently utilizing Nestjs for sending data to a Mqtt Broker. However, I am facing an issue where it sends both the pattern and data instead of just the data in this format: { "pattern": "test/test", "data": " ...

How can I subtract a value from my array in Angular?

I've been troubleshooting this problem for a while now and I'm hoping that someone here can assist me with finding a solution. The issue at hand involves an array object containing various values such as id, title, amountCounter. Specifically, t ...

Exploring nested JSON objects within an array using ngFor directive

My application uses Angular 6 and Firebase. I am trying to showcase a list of all appointments. Below is my approach: service.ts getRDV() { this.rdvList = this.firebase.list('/rdv'); return this.rdvList; } Model: export class RDV { key: ...

What is the reason behind VS Code not showing an error when executing the command line tsc shows an error message?

Deliberately introducing a typo in my code results in an error. Here is the corrected code: declare const State: TwineState; If I remove the last character and then run tsc on the command line, it throws this error: tsc/prod.spec.ts:7:22 - error TS2304: ...

What is the proper way to include type annotation in a destructured object literal when using the rest operator?

When working with objects, I utilize the spread/rest operator to destructure an object literal. Is there a way to add type annotation specifically to the rest part? I attempted to accomplish this task, but encountered an error when running tsc. const { ...

What is the best way to display API error messages to the user?

When a user tries to upload a file that is not an image, I need to display the error message returned from a REST API. The JSON response received from the API will look something like this: { "publicError": "Could not be uploaded, it is not an image! ...

The initial Get request does not receive data upon first attempt

In the process of developing an Angular project, I am faced with the task of retrieving data from my backend by making requests to an API. However, before the backend can fetch the required data, certain parameters must be sent through a post request. Once ...

Is there a way to remove an event listener once the associated button has been clicked within the given code?

Is there a way to prevent this event from triggering once the "dispensed" button is clicked in another module? Here is the code snippet: stopDrugOrder(e: Event, drugOrder: any, drugName: string) { const confirmDialog = this.dialog.open(SharedConfirmat ...

The absence of a semicolon following the interface declaration is the issue

I am facing a slight issue with ESLint and Typescript, particularly regarding semicolons after declaring interfaces. Additionally, I utilize VSCode as my editor with automatic formatting upon saving. Below is the configuration in my .eslintrc.json file: ...

When employing the pipe function within *ngFor, the webpage's refresh may vary, causing occasional updates

Utilizing angular2-meteor, I have already implemented pure: false. However, the pipe seems to be running inconsistently. For more details on the issue, please refer to my comments within the code. Thank you. <div *ngFor="#user of (users|orderByStatus) ...

Building state from multiple child components in Next.js/React: Best Practices

To better illustrate this concept, I suggest checking out this codesandbox link. This is a follow-up to my previous question on Stack Overflow, which can provide additional context. Currently, when interacting with the child elements (such as inputs), th ...

Using Angular, a function can be called recursively directly from within the HTML

I'm struggling with loading an image because the method getUserProfileImage() is getting triggered multiple times within a loop. Is there a way to ensure the method is only called once during each iteration? I understand that this issue is related to ...

Tips on preventing image previews from consuming too much text data while updating a database in Angular 12 using Material UI for image uploads within a FormGroup object

Currently working with Angular 12 and Angular Material for image uploads with preview. I have a formgroup object below, but I'm running into issues with the 197kb image preview text being inserted into the database. Despite trying setValue/patchValue/ ...

Issue with rest operator behavior in TypeScript when targeting es2018

This specific code snippet functions properly in the TypeScript Playground... class Foo { constructor(...args: any[]) { } static make(...args: any[]): Foo { return new Foo(...args); } } Example However, when trying to incorpora ...

TypeORM - Establishing dual Foreign Keys within a single table that point to the identical Primary Key

Currently, I am working with TypeORM 0.3.10 on a project that uses Postgres. One issue I encountered is while trying to generate and execute a Migration using ts-node-commonjs. The problem arises when two Foreign Keys within the same table are referencing ...

Issues arising from an aging Angular project

I'm currently facing an issue with installing node and typescript for an older angular project that I have inherited. This project is using angular 2.4.10 After downloading and installing node version 6.9.5 from the executable file, I proceeded to in ...