When a subclass method overrides a property in the base type and returns `super`, it cannot be reassigned to

If I wish to enhance the functionality of the Promise class by customizing the then() method to execute something before calling super.then():

class ExtendedPromise<T> extends Promise<T> {
  then(...x: Parameters<InstanceType<typeof Promise<T>>["then"]>) {
    console.log("Do something here");
    return super.then(...x);
  }
}

Playground

In TypeScript, there is an error stating that this override is not compatible with the same property in the parent type because unknown cannot be assigned to type TResult1 | TResult2. But why does this occur? I am accepting the exact parameters as the parent type and essentially returning the value from super, so all types should match, right?

Answer №1

The reason for this behavior is that the Promise's then method has its own set of generics which may not align with the generic type of the overall Promise. When you do not provide these generics for the then function, it defaults to <T, never>. One way to work around this is by statically typing the function parameter types and adding

<TResult1 = T, TResult2 = never>
after the then call. Unfortunately, providing generics directly to the then method in a string index does not work as intended. To achieve what you want, you can try something like this:

class ExtendedPromise<T> extends Promise<T> {
    then<TResult1 = T, TResult2 = never>(...x: Parameters<InstanceType<typeof Promise<T>>["then"]<TResult1, TResult2>>) { 
        console.log("Do something");
        return super.then(...x);
    }
}

Despite attempts, the above approach has shown limitations.

If you opt for explicitly typing the parameters, here's an alternative code snippet:

class ExtendedPromise<T> extends Promise<T> {
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) {
        console.log("Do something");
        return super.then(onfulfilled, onrejected);
    }
}

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

Protractor encounters an error stating "No element found with specified locator" after attempting to switch to an

I've been attempting to download an embedded PDF from a webpage using Protractor selenium. However, I seem to be stuck when it comes to actually downloading the file as I always encounter the following error: Failed: No element found using locator: ...

How to set an already existing anonymous object to a property within the data property in VueJS

Help needed for a beginner question let myOptions: { chart: { height: 350, type: 'bar' }, colors: ["#800000"] }; let vueExample = new Vue({ el: '#example', components: { apexchart: VueApexCh ...

Typescript type cast is not parsed by Prettier

I am currently using Prettier version 1.17.1 and TypeScript 3.4.5 in combination with create-react-app. Every time I attempt to utilize the x as T syntax in TypeScript for type casting, I encounter the following error: src/Form.tsx [error] src/Form.tsx: ...

"Utilizing provideMockStore in NgRx 8 for setting the state of a specific State Slice

I have been working on testing a smart component for my NgRx implementation, and the test setup looks like this: describe( 'Component', () => { let store: MockStore<State>; beforeEach( async( () => { TestBed.configureTesting ...

Best method for locating type declarations in TypeScript 2.0

Ever since typescript 2.0 rolled out, the use of typings has been replaced with npm install @types/<package-name>. In the old typings system, we had the typings search command for package searches. But now I wonder - what is the standard way to sear ...

Converting a string to HTML in Angular 2 with proper formatting

I'm facing a challenge that I have no clue how to tackle. My goal is to create an object similar to this: { text: "hello {param1}", param1: { text:"world", class: "bla" } } The tricky part is that I want to ...

Service Activation Button Click Event

When coding, I designated the path as follows: { path:'home', component: homeComponent; } In app.component.html: <button (click)="routerLink='/home'" An error occurred here Are you trying to navigate to the home page by ...

Creating a custom Angular HTTP interceptor to handle authentication headers

Necessity arises for me to insert a token into the 'Authorization' header with every HTTP request. Thus, I created and implemented an HttpInterceptor: @Injectable() export class TokenInterceptor implements HttpInterceptor { constructor(public ...

The absence of type-safety in the MUI System sx is a glaring issue

I want to ensure that the TypeScript compiler can identify typos in my MUI System sx props: import { Box, SxProps, Theme, Typography } from '@mui/material' const sxRoot: SxProps<Theme> = { width: '100vw', height: '10 ...

Preserve Inference in Typescript Generics When Typing Objects

When utilizing a generic type with default arguments, an issue arises where the inference benefit is lost if the variable is declared with the generic type. Consider the following types: type Attributes = Record<string, any>; type Model<TAttribu ...

Tips for creating a custom waitForElementText function in Playwright

I need to implement a function called waitForElementText() in playwright. For example, I have headers labeled with the CSS selector '.header-name' on each page. When navigating from the Home page to the Users page, I provide two parameters to ...

Exploring the process of selecting checkboxes in Angular 6

I'm currently learning Angular 6 and I have a requirement to mark checkboxes based on specific IDs from two arrays: this.skillArray = [ {ID: 1, name: "Diving"}, {ID: 2, name: "Firefighting"}, {ID: 3, name: "Treatment"}, ...

Checking nested arrays recursively in Typescript

I'm facing difficulty in traversing through a nested array which may contain arrays of itself, representing a dynamic menu structure. Below is how the objects are structured: This is the Interface IMenuNode: Interface IMenuNode: export interface IM ...

Managing situations within the RxJS pipeline

I have an Observable called leadChanged$, which I can easily connect to the template using the async pipe. leadChanged$: Observable<LeadModel>; this.leadChanged$ = this.leadsDataService.leadChanged$.pipe( map((res) => ({ ... ...

What is the most efficient method for line wrapping in the react className attribute while utilizing Tailwind CSS with minimal impact on performance?

Is there a more efficient way to structure the className attribute when utilizing tailwind css? Which of the examples provided would have the least impact on performance? If I were to use an array for the classes and then join them together as shown in e ...

Tips for setting up nested folders using Node.js on a Windows machine:

Is there a way to use Nodejs in Windows 10/11 to create a parent folder and then add a new folder inside of that parent folder, like this: parent/child within the Documents folder? ...

What's with all the requests for loaders on every single route?

I'm in the process of setting up a new Remix Project and I'm experimenting with nested routing. However, no matter which route I navigate to, I keep encountering the same error: 'You made a GET request to "/", but did not provide a `loader` ...

Angular does not permit the use of the property proxyConfig

Click here to view the image I encountered an issue when attempting to include a proxy config file in angular.json, as it was stating that the property is not allowed. ...

Is there a way to utilize an Event Emitter to invoke a function that produces a result, and pause until the answer is provided before continuing?

Looking for a way to emit an event from a child component that triggers a function in the parent component, but with a need to wait for a response before continuing. Child @Output() callParentFunction = new EventEmitter<any>(); ... this.callParen ...

Encountering a 500 (Internal Server Error) while attempting to fetch a single document from MongoDB without utilizing the

I am currently developing my first project using the MEAN stack, and I'm facing a challenge with retrieving a single element from MongoDB. The specific page I'm working on is meant to allow users to edit an item from a list displayed on the main ...