Implementing method overrides in TypeScript class objects inherited from JavaScript function-based classes

I am facing a challenge with overriding an object method defined in a JavaScript (ES5) function-based class:

var JSClass = function() {
  this.start = function() {
    console.log('JSClass.start()');
  }
}

When I call the start() method, it prints as expected:

let o1 = new JSClass();
o1.start();
// prints: JSClass.start()

However, when I attempt to extend this object with a TypeScript class like so:

class TSClass extends JSClass {
  start() {
    super.start();
    console.log('TSClass.start()');
  }

  otherStart() {
    this.start();
    console.log('TSClass.otherStart()');
  }
}

... the TSClass::start() is never called. Only the start() method defined in the JSClass.

let o2 = new TSClass();
o2.start();
o2.otherStart();

This results in:

JSClass.start()
JSClass.start()
TSClass.otherStart()

The desired output would be:

// by calling: o2.start();
JSClass.start()
TSClass.start()
// by calling: o2.otherStart();
JSClass.start()
TSClass.start()
TSClass.otherStart()

Is this behavior intentional? If so, what is the workaround for extending ES5 object methods with TypeScript?

Check out the live demo here: https://jsfiddle.net/martinsikora/2sunkmq7/

Edit: I found a solution that worked for me.

class TSClass extends JSClass {

  constructor() {
    var oldStart = this.start;
    this.start = () => {
      oldStart.call(this);
      console.log('TSClass.start()');
    }
  }
  // ...
}

Now the functionality works as expected.

Answer №1

The issue you're facing is that the start method is being added to JSClass as a class member instead of a class method.
To convert it into a method, you should add it to the prototype:

var JSClass = function () {}

JSClass.prototype.start = function () {
    console.log('JSClass.start()');
}

After making this change, the following code:

let o2 = new TSClass();
o2.start();
o2.otherStart();

Will produce the output:

JSClass.start()
TSClass.start()
JSClass.start()
TSClass.start()
TSClass.otherStart()

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

Automatically updating the JavaScript content on a webpage without having to refresh the entire HTML page, based on the changing

Is there a way to adjust the opacity change rate of my nav bar automatically without the need to refresh the page? The current opacity change rate is based on the width of the window, but once the page is loaded, adjusting the width does not affect the rat ...

Exploring ways to expand the theme.mixins feature in MUI 5

Currently, I am in the process of updating Material UI from version 4 to 5 and encountering challenges with my existing theming. Since we are using typescript, it is important to include the appropriate types when extending themes. I intend to include th ...

Secure HyperText Transfer Protocol prevents JavaScript from executing

My website's HTTPS version is having trouble loading JavaScript. All scripts are hosted on the same server. I've attempted: <script type="text/javascript" src="https://server.tld/js/jquery.js"> <script type="text/javascript" src="//ser ...

Karma Jasmin is puzzled as to why her tests are failing intermittently, despite the absence of any actual test cases

In this snippet, you will find my oninit method which I am instructed not to modify. ngOnInit(): void { this.setCustomizedValues(); this.sub = PubSub.subscribe('highlightEntity', (subId, entityIdentifier: string) => { ...

Is there a child missing? If so, add a class

I need to add the class span.toggle if the parent element of li does not have a child ul element. click here to view on codepen Snippet of HTML: <html lang="en"> <head> <meta charset="UTF-8> <title>No Title</title>& ...

I'm having trouble establishing a connection with the Appwrite platform

Encountered an issue while trying to connect to appwrite. The specific error message is: Uncaught (in promise) TypeError: Failed to construct 'URL': Invalid URL at Account.<anonymous> (appwrite.js?v=d683b3eb:932:19) at Generator.nex ...

Starting a tab just once

I have successfully created 4 static HTML pages that include: Home About Services Contact Each page contains a link that leads to another static page named myVideo.html, which plays a video about me in a new tab. The link is available on every page so ...

Generating a 3D face using three coordinates in Three.js

Currently, I have implemented code that allows me to load, render, and display a STL object using Vue.js and Three.js. My goal now is to replace the currently selected plane with a new face. I've managed to extract the 3 vertices of the clicked-on fac ...

JQuery AJAX not retrieving data after $.post request

I am currently facing a challenge with a specific JQuery $.post request to a PHP-based processor. To troubleshoot, I set up a test page containing the following code: It's important to note that this is hosted on a subdomain, but there are no cross-d ...

What steps are involved in importing remark-gfm into next.config.js?

I am interested in incorporating MDX into next.js with the remark-gfm plugin. After discovering the Next.js Docs on MDX, I decided to follow their guidelines and added an import statement. // next.config.js import remarkGfm from 'remark-gfm;' co ...

Does the downloading of images get affected when the CSS file has the disabled attribute?

Is it possible to delay the download of images on a website by setting the stylesheet to 'disabled'? For example: <link id="imagesCSS" rel="stylesheet" type="text/css" href="images.css" disabled> My idea is to enable the link later to tri ...

Vue.js: Select a different div within the Vue object instead of the one that is bound

I am currently utilizing Vue and Leaflet to showcase polygons (zones) on a map and exhibit relevant information (messages) upon clicking on specific polygons. The div responsible for rendering these messages has the unique id "#messagearea" and is connec ...

Retrieve the property values of `T` using a string key through the `in

Having trouble accessing a property in an object using a string index, where the interface is defined with in keyof. Consider the following code snippet: interface IFilm { name: string; author: string; } type IExtra<T extends {}> = { [i ...

I am having difficulty with my JavaScript code not being able to interpret the JSON output from my PHP code. Can anyone help me troubleshoot

Having trouble working with an AJAX call and handling the JSON object it generates in JavaScript? Here's a sample snippet of PHP code returning the JSON object: echo json_encode(array("results" => array(array("user" => $member['user'] ...

In IE8, submitting an Ajax request almost always results in an error being

This piece of code seems to be causing some trouble, as it works fine in all browsers except for IE8 on an XP machine. No matter what I try, the error function keeps getting triggered specifically in IE8. I've experimented with different dataTypes lik ...

The incorrect date selection made by the Datepicker feature in the Vue / Buefy component

Currently, I am utilizing Vue / Buefy as a datepicker in the form on a specific page (2nd step). You can find the page here: An issue has arisen where the date of birth input is sometimes recorded inaccurately. For instance, the user selects June 5th, 197 ...

Tips on restricting dates to be equal to or earlier:

I have written a code to determine if two given dates are equal or not. The code should allow for the current date to be smaller than or equal to the provided date, but it should not allow for it to be greater. var date = '10-11-2015'; var toda ...

Paste the current webpage's URL into a fresh alert popup using javascript"

I found myself spending hours trying to figure out the best way to create a JavaScript function that would copy the current URL and display it in a new alert window. Imagine a scenario where a user clicks on "Share this page" and a new alert window pops u ...

How can the datetime value of the Apex Charts datapoint be shown in the tooltip?

I'm struggling to find the proper location within the w.globals object to display the x-axis value, which is a datetime, in the tooltip of the datapoint. var chartOptions = { ... xaxis: { type: "datetime" }, tooltip: { x: { format: " ...

typescript throwing an unexpected import/export token error

I'm currently exploring TypeScript for the first time and I find myself puzzled by the import/export mechanisms that differ from what I'm used to with ES6. Here is an interface I'm attempting to export in a file named transformedRowInterfac ...