Different types of promises can be returned in Typescript

I am experiencing some peculiar issues with my TypeScript code.

export interface Result<T> { data: T};
export type ErrorResult = Result<string>;
export type ErrorResponse = Promise<ErrorResult>;
export type SuccessResult = Result<any>;
export type SuccessResponse = Promise<SuccessResult>;

Why does TypeScript prevent me from defining a function like this?

export async function stuff(): ErrorResponse | SuccessResponse {}

Instead, it seems to only allow me to write:

export async function stuff(): Promise<ErrorResult | SuccesResult> {}

Answer №1

In the realm of JavaScript, a function identified as async consistently delivers a Promise. This promise can be embraced with await to fetch an internal value. (Discover more on MDN)

For instance.

async function getName() {
  // Illustrative internals..
  return "Celine";
}

const theNamePromise = getName();
//    ^^ This is a Promise<string>

const theName = await getName();
//    this is a string ("Celine")

Edit: Tailored specifically for your illustration:

(Keep in mind, I don't have a definitive answer here. However, through some experimentation, I uncovered a few mildly intriguing discoveries. The following is a brief summary of my findings, and here is the example code I was playing with)

It's crucial to recognize that

Promise<string> | Promise<number>
and Promise<string | number> are similar but not entirely interchangeable from TypeScript's perspective.

To elaborate using an example, imagine if we applied your Result<T> type similarly:

function getResult(): Result<string> | Result<number> {
    // This return statement prompts a TS error
    return {
        data: Math.random() > 0.5 ? "test" : 5,
    };
}

If you input this into TS, an error will arise because the returned value belongs to type { data: string | number; }, not

{ data: string; } | { data: number; }
.

However, that type is compatible with Result<string | number>

function getResult2(): Result<string | number> {
    // This is acceptable
    return {
        data: Math.random() ? "test" : 5,
    };
}

This showcases a discrepancy in how TS interprets these types, yet it doesn't necessarily elucidate why the primary type returned by an async can't be an amalgamation of two Promise<T> types. Regrettably, I lack a comprehensive explanation there.

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

Interfaces are limited to extending an object type or a combination of object types that have statically defined members

Having trouble utilizing TextFieldProps in my code. Any tips on how to effectively use TextFieldProps? Any help is appreciated. https://i.sstatic.net/mzTfe.png import TextField, { TextFieldProps } from '@mui/material/TextField'; import { colorTh ...

Is ts-node necessary for using TypeScript in Node.js?

Having trouble setting up a Node.js application in Visual Studio Code using TypeScript due to issues with importing modules. Initially, I created an index.ts file with the import statement -> import config from './app/config.json'; This resu ...

Removing special characters when pasting into text box in Angular 2 or higher versions

To ensure that special characters are trimmed or removed when pasting into a textbox inside the TypeScript component file (with extension .ts), utilize a function within the TypeScript component itself. The modified text should be displayed in the textbox ...

Angular Material's dialog modal swiftly closes without delay

Could you please explain why the modal opens and then closes instantly when I click on the Create Project button? https://example.com/edit/angular-code I am trying to display a component within the modal using Angular Material. portafolio.component.ts ...

Ways to assign values to an array within an object

I'm attempting to transfer the contents of one array into an array within an object, but I keep encountering this error: Type 'any[]' is not assignable to type '[]'. Target allows only 0 element(s) but source may have more. Here ...

Build process halted: Error encountered: Debug assertion failed. Incorrect expression detected

In my TypeScript library, I have a class that compiles to JavaScript: ClassName = ClassName_1 = class ClassName{ ... } ClassName = ClassName_1 = decorate([ ...]) However, when I compile it with an Angular frontend that relies on this library using the f ...

Issue with retrieving properties in Angular template due to undefined values in HTML

As a newbie to Angular, I am dedicated to improving my skills in the framework. In my project, I am utilizing three essential files: a service (Studentservice.ts) that emits an observable through the ShowBeerDetails method, and then I subscribe to this ob ...

A Promise signature allows for the compilation of function bodies that return undefined

The compiler error that I expected to see when using this function does not actually occur. The function body is capable of returning undefined, yet the type signature does not mention this possibility. async function chat(_: at.ChatLine): Promise<Arr ...

Determining the data type of a generic variable within an Angular component

I'm currently in the process of developing a versatile component that can handle data of only two specific types: interface X{ name: string, path: string, type: string, } interface Y{ name: string, path: string, } Both types X a ...

Guide on how to develop a custom extension method tailored for a specific type of generic class in TypeScript

As part of a semi-educational side project I am currently developing, there is a TypeScript interface which specifies the presence of an id property on any object that implements it. Throughout this application, you will often find arrays Array<> con ...

Can the type of a prop be specified in the parent component before it is passed down to the children components that utilize the same prop?

In my codebase, I have a component called NotFoundGuard. This component only renders its children if a certain condition is true. Otherwise, it displays a generic fallback component to prevent redundancy in our code. I am trying to figure out if there is ...

Issue with Stenciljs custom event not triggering using @Listen decorator

I've been trying to grasp the workings of the custom event emitter. While my mouse events seem to be functioning properly, I'm encountering issues with the custom events. Despite emitting correctly, it appears that the listener is not capturing t ...

Are there alternative methods for incorporating react-multi-carousel in a project utilizing NEXT.js and React/Typescript?

I installed the react-multi-carousel module and configured a simple carousel, but it's not functioning properly. The issue seems to be related to the absence of <li> tags. Here is the HTML that was rendered: <ul class="react-multi-caro ...

Several cucumber reports are showing an error message containing special characters

I am encountering an issue in the multiple cucumber report where error messages are being displayed with special characters. Is there a way to format them properly? I am currently learning Playwright, Typescript, and CucumberJs and generating reports for m ...

Can you explain the distinction between using [ngFor] or [ngForOf] in Angular 2?

From what I gather, both serve the same purpose. However, ngFor operates similar to collections. ngForOf functions more like generics. Am I correct in my understanding? Or can you provide more insight on the differences between ngFor and ngFor ...

Guide on transforming an array of objects into a fresh array

I currently have this array: const initialData = [ { day: 1, values: [ { name: 'Roger', score: 90, }, { name: 'Kevin', score: 88, }, { name: 'Steve&apo ...

What is the process for setting the active state for HtmlBodyElement?

I attempted to use the following method: document.querySelector('body').setActive(); However, I encountered an error: TS2339: Property 'setActive' does not exist on type 'HTMLBodyElement'. Any suggestions on how to resolve t ...

What is the reason for property x not appearing on type Y despite module augmentation efforts?

I've been experimenting with modules and came across a scenario that I'm struggling to fully understand. This is how I have everything set up: import MyTesterImpl from "./MyTesterImpl"; declare module "./MyTesterImpl" { int ...

To properly format the date value from the ngModel in Angular before sending it to the payload, I require the date to be in the format

When working with Angular 9, I am facing an issue where I need to format and send my date in a specific way within the payload. Currently, the code is sending the date in this format: otgStartDate: 2021-07-20T09:56:39.000Z, but I actually want it to be for ...

Issue with detecting window resize event in Angular 7 service

I have a unique service that utilizes a ReplaySubject variable for components, but strangely the WindowResize event isn't triggering. import { Injectable, HostListener } from '@angular/core'; import { ReplaySubject } from 'rxjs'; ...