Do constructors in TypeScript automatically replace the value of `this` with the object returned when using `super(...)`?

I’m having some trouble grasping a concept from the documentation:

According to ES2015, constructors that return an object will automatically replace the value of “this” for any instances where “super(…)” is called. The constructor code must be able to handle and override any return values from “super(…)” with “this.”

This explanation feels a bit unclear to me. Can someone provide more clarity on what exactly is happening here?

Answer №1

The concept of the super "function call" in JavaScript can be quite perplexing. In normal classes where no objects are returned, the keyword this simply refers to the current instance of the class being constructed. When calling super(), it essentially operates on this same reference, resulting in the final constructed object being an instance of the subclass:

class Foo {
    a = 10;
    constructor() { }
}

class Bar extends Foo {
    z: number;
    constructor() {
        super();
        this.z = 1;
    }
}

const b = new Bar();
console.log(b); // Bar: {a: 10, z: 1}
console.log(b instanceof Bar); // true

However, if the superclass does return a value from its constructor, then somehow this in the subclass adopts that value. This allows subsequent references to this to point to the same object returned by the superclass. As a result, the subclass behaves "normally", although the constructed object is not technically an instance of the class:

class Foo {
    constructor() {
        return { a: 10 };
    }
}

class Bar extends Foo {
    z: number;
    constructor() {
        super();
        this.z = 1;
    }
}

const b = new Bar();
console.log(b); // {a: 10, z: 1}
console.log(b instanceof Bar); // false

This leads to the idea that when invoking super(), it's like saying "call the superclass constructor as if it were a function and check if it returns something". If it does, then implicitly assign the result of that function to this. While you can't directly assign to this, this process happens automatically behind the scenes. Observing how super constructors work when downleveling code to an earlier version of JS before the introduction of the class syntax reveals a similar mechanism:

function Bar() {
    var _this = _super.call(this) || this;
    _this.z = 1;
    return _this;
}

In this scenario, the original this is replaced with a new _this variable.

Link to playground code

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

Encountered in the Angular library: NG0203 error stating that inject() should only be invoked within an injection context like a constructor, factory function, or field initializer

Having recently updated my Angular project from version 9 to 15, I encountered the following issue. Any assistance would be greatly appreciated as I have been struggling with it for over 2 weeks. The problem lies within app-lib.module.ts in the Angular li ...

Having issues with @ts-ignore in Typescript on a let variable that is not reassigned?

JOURNEY TO THE PROBLEM My current task involves destructuring a response obtained from an Apollo useLazyQuery, with the intention to modify one variable. In a non-Typescript environment, achieving this would be straightforward with just two lines of code: ...

Library for Typescript on npm

My project involves a collection of base classes in TypeScript. Within a web application built with React and written in TypeScript, I am looking to integrate a library called 'Plain Old TypeScript objects', which defines all the data types. Let& ...

Using React to make an API call without utilizing hooks

Hello, I am currently working on developing a webpart using SharePoint and React. However, I am facing some issues with fetching data from a simple API. export default class Testing100 extends React.Component<ITesting100Props, {}> { constructor(p ...

Incorrect typings being output by rxjs map

combineLatest([of(1), of('test')]).pipe( map(([myNumber, myString]) => { return [myNumber, myString]; }), map(([myNewNumber, myNewString]) => { const test = myNewString.length; }) ); Property 'length' does not ...

Troubleshooting a deletion request in Angular Http that is returning undefined within the MEAN stack

I need to remove the refresh token from the server when the user logs out. auth.service.ts deleteToken(refreshToken:any){ return this.http.delete(`${environment.baseUrl}/logout`, refreshToken).toPromise() } header.component.ts refreshToken = localS ...

ESLint warning: Potentially risky assignment of an undetermined data type and hazardous invocation of an undetermined data type value

Review this test code: import { isHtmlLinkDescriptor } from '@remix-run/react/links' import invariant from 'tiny-invariant' import { links } from '~/root' it('should return a rel=stylesheet', () => { const resp ...

Error: Namespace declaration does not have a type annotation - TypeScript/Babel

After creating my app using the command npx create-react-app --typescript, I encountered an issue with generated code and namespaces causing Babel to throw an error. Here are the steps I took to try and resolve the issue: I ejected the project Updated b ...

Connect a click event from one component to another component

Can Angular bind a click event dynamically from a component to another existing component on the page? Check out this image for reference. In my app, I have 4 simple components - a shell component that defines the layout, a header component (blue outline) ...

Is it possible to dynamically pass a component to a generic component in React?

Currently using Angular2+ and in need of passing a content component to a generic modal component. Which Component Should Pass the Content Component? openModal() { // open the modal component const modalRef = this.modalService.open(NgbdModalCompo ...

The creation of a Firebase user account with the specified email and password

I'm currently facing an issue while creating a new user with email and password using firebase authentication. The problem arises when I try to access the displayName from the returned async call before the updateProfile function, as it returns a null ...

Exploring TypeScript and React Hooks for managing state and handling events

What are the different types of React.js's state and events? In the code snippet provided, I am currently using type: any as a workaround, but it feels like a hack. How can I properly define the types for them? When defining my custom hooks: If I u ...

What is the reason for Object.keys not returning a keyof type in TypeScript?

Wondering why Object.keys(x) in TypeScript doesn't return the type Array<keyof typeof x>? It seems like a missed opportunity as Object.keys outputs that by default. Should I report this on their GitHub repo, or should I just submit a pull reques ...

Tips for transferring data to an entry component in Angular 2 using ng-bootstrap modal

I've been grappling with sending data to a custom modal content component in Angular 2. My objective is to have the flexibility of calling this modal from any other component without duplicating code. Despite my efforts, including referencing the "Com ...

Errors are not displayed or validated when a FormControl is disabled in Angular 4

My FormControl is connected to an input element. <input matInput [formControl]="nameControl"> This setup looks like the following during initialization: this.nameControl = new FormControl({value: initValue, disabled: true}, [Validators.required, U ...

Difficulty fetching data on the frontend with Typescript, React, Vite, and Express

I'm currently working on an app utilizing Express in the backend and React in the frontend with typescript. This is also my first time using Vite to build the frontend. While my APIs are functioning correctly, I am facing difficulties fetching data on ...

Error: Unable to set value, val.set is not a defined function for this operation (Javascript

Encountering a problem while running the function val.set(key, value), resulting in a type error TypeError: val.set is not a function within the file vendor-es2015.js. Here's the simplified code snippet: import { Storage } from '@ionic/storage& ...

The dynamic fusion of Typescript and Angular 2 creates a powerful

private nodes = []; constructor(private nodeService: NodeService) {} this.nodeService.fetchNodes('APIEndpoint') .subscribe((data) => { this.nodes.push(data); }); console.log(this.nodes) This ...

Restrict the parameter type using a type predicate

How can I effectively narrow types based on the value of a single field in TypeScript? It seems that using type predicates may not be working as expected to narrow down the types of other parameters within a type. Is there a way to ensure correct type na ...

"Error encountered while executing a code snippet using Navalia in TypeScript

I have been attempting to execute this code snippet from https://github.com/joelgriffith/navalia but despite my efforts, I have not been able to get it running smoothly without encountering errors: navaliatest.ts /// <reference path="typings.d.ts" /&g ...