Guide on adding a custom function to a class in TypeScript

Is there a way to inject a custom function into my class from the variable functions? I need assistance with this.

This is my code snippet:

const functions = {
    foo: () => console.log('foo') 
}

class ParentBase {
    parentHello() {
        console.log('parentHello')
    }
}

function Base() {
    class BaseClass extends ParentBase { }
    BaseClass.foo = functions['foo']
    return BaseClass;
} 

const Class = Base();
const instance = new Class(); 

instance.parentHello() // it works
instance.foo() // foo  is not a function 

Answer №1

To add a new method directly to the class declaration, you can do the following:

class BaseClass extends ParentBase { 
  foo() {functions["foo"](); }
}

If you need the method name to be dynamic, computed method names can be used like this:

class BaseClass extends ParentBase { 
  [window.location]() {functions["foo"](); }
}

If you want to dynamically inject a new method (such as conditionally or in a loop), write into BaseClass.prototype:

BaseClass.prototype.foo = functions["foo"];

To create a non-enumerable property, use Object.defineProperty like this:

Object.defineProperty(BaseClass.prototype, "foo", {
  value: functions["foo"],
});

Below is a demonstration of adding methods to a class:

class ParentBase {
    parentHello() {
        console.log('parentHello')
    }
}

function Base() {
    class BaseClass extends ParentBase {
      instanceMethod() { console.log("BaseClass.prototoype.test", this); };
      static classMethod() { console.log("BaseClass.classMethod", this); };
    }
    BaseClass.classMethod2 = function() { console.log("BaseClass.classMethod2", this); };
    BaseClass.prototype.instanceMethod2 = function() { console.log("BaseClass.prototype.instanceMethod2", this); };
    Object.defineProperty(BaseClass.prototype, "instanceMethod3", { value() { console.log("BaseClass.prototype.instanceMethod3", this); } });
    
    return BaseClass;
} 

const Class = Base();
const instance = new Class();

Class.classMethod();
Class.classMethod2();

instance.instanceMethod();
instance.instanceMethod2();
instance.instanceMethod3();

Answer №2

There are two ways to access properties:

  • Using instances
  • Using classes

If you are adding properties to the class but trying to access them through an instance, you need to utilize mixins. Mixins are a list of utility functions that can be shared among multiple classes.

To inject properties into instances, you can either use a constructor-based approach or add them to the prototype.

class ParentBase {
  parentHello() {
    console.log('parentHello')
  }
}

const mixin = {
  foo: function() { console.log('foo') },
  bar: function() { console.log('Bar') },
  fooBar: function() { console.log('foo-bar') }
}

function Base() {
  class BaseClass extends ParentBase {}
  Object.assign(BaseClass.prototype, mixin)
  return BaseClass;
}

const Class = Base();
const instance = new Class();

instance.parentHello() // it works
instance.foo() // throws error because 'foo' is not a function
instance.fooBar()


It's important to note that functions/properties added to the prototype are shared across instances. Therefore, it is recommended to only add functions and not variables to avoid introducing side effects.

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

Pass data from a JavaScript function to Objective-C in Xcode by returning an array

How can I retrieve an array of strings from Javascript in my iPhone app code? I am calling a Javascript function, and once it completes, I need to send the array of strings back to the Objective-C code. What is the best way to return the array and how can ...

When representing audio as sound bars on a canvas, the previous drawing is retained if canvas height is not specified

After obtaining an audioBuffer containing an audio clip, I proceed to create a visualization by drawing a series of sound bars in the shape of a circle: const { audioContext, analyser } = this.getAudioContext(); const source = audioContext.createBufferSou ...

Angular directives are not triggering window level events as anticipated

This code snippet might be a bit confusing. Take a look at the code below: //html <div id="test1" test></div> <div id="test2" test></div> //module var myApp = angular.module(&ap ...

What are the benefits of incorporating an external API with Next.js API routes?

I've recently started using Next.js and I'm curious about the purpose of export default function handler since we can directly fetch data from APIs. In my HTML code, I have the following snippet. When the submit button is clicked, the sendformDa ...

Creating image paths for a list of items in reactjs can be achieved by mapping through the list

My goal is to display a list of items, with each item being assigned an image based on its ID: private static renderItemsTable(products: Product[]) { return <table className='table'> <thead> <tr> ...

What is the best way to choose a random ID from a table within specified time intervals in MySQL?

I need to retrieve a random ID from the table nodes within the last 15 seconds. I attempted the following code, but it produced a lengthy output: const mysql = require('mysql'); const connection = mysql.createConnection({ host ...

Adding padding to navigation items in Bootstrap 5 when the collapsible navbar is expanded

How can I modify the CSS rules for nav items in a Bootstrap 5 collapsible navbar to have proper padding and margins only when they are expanded and the buttons are on the right side? <!DOCTYPE html> <html lang="en"> <head> <meta ...

What is the best approach to implementing a blur function for a specific input within a parent component?

I have created a custom input field as a separate component. I want to include multiple input fields in the parent component using directives: <app-input ...></app-input> My goal is to pass the blur event/function to the parent component speci ...

Error Loading JQuery: The function $() is not recognized in the Shopify platform

I seem to be overlooking something obvious. I am using Shopify and have included jQuery in the head section of the theme.liquid file: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> This script is placed rig ...

Ways to loop through an array of daytime values and exhibit just the records for the current week

ng-repeat="day in task.DailyWorks | limitTo : weekdays.length: weekStart" This iteration process enables me to showcase the daily work records in a structured format within the table columns. The feature allows for seamless navigation between different we ...

Data retrieval issue with ng-table displaying information queried from HTTP request

I have been attempting to create an ng-table using ajax data with angularjs and rails. Despite successfully retrieving the data through an http get request, I am encountering difficulties appending it to my table as it always displays no records. Below is ...

Verify the inheritance of prototype, not the individual instance

Assume I have: function Pet(){} Pet.prototype.breathe = function(){} And function Cat(){} Afterwards, I execute: Cat.prototype = Object.create(Pet.prototype) Cat.prototype.purr = function(){} I am aware that var cat = new Cat() console.log(cat inst ...

Struggling to create a C# class structure for a JSON string

Currently, I am faced with the challenge of deserializing an object into a custom class. The string that will be passed to me has the following format: {nodename:"node1", version:"v1", PARM1:"p1", PARM2:"p2" ,…, PARAMN:"pn"}. From what I understand, I ...

Upon initial execution, a Nextjs error occurs: Unable to locate the module 'caniuse-lite/data/features/css-unicode-bidi'

Encountered an error while starting my nextjs project, here's the issue Error - ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[2].oneOf[8].use[1]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/s ...

Python on the server side generating a downloadable zip file

After passing a parameter from my client to a python script on the server through a GET request, the script initiates a process that results in the creation of a zip file. However, upon making an AJAX call in my client-side JavaScript, I am only able to co ...

Should I use jQuery's .on() method or plain JavaScript function()?

I am currently working on pages that are constructed using ajax calls to the server, which means I am using .on() to attach event handlers to new items. However, I am curious whether it would be more effective to use the traditional javascript:function() ...

After pushing to history in React, the rendered component fails to display on the screen

I am in the process of developing a React application. Here are the dependencies I am currently using: "react": "^17.0.2", "react-dom": "^17.0.2", "react-helmet": "^6.1.0", "react-router" ...

How can jQuery verify if the event outcome matches a specific element?

Check out the code snippet below: $('html').on("click", function (e) { if(!$(e).is($element)) { hideResults(); } }); I attempted to use this code, but unfortunately it did not yield the desired outcome. The element in question i ...

Steer clear of utilizing Number() when working with scientific notation

I am attempting to perform the following task Number("0.00000000000122") yields 1.22e-12 However, my goal is to convert that number from a String to a Number. console.log(Number("0.00000000000122")) ...

What is the best way to display a number or integer using axios?

Need help retrieving the integer from the response obtained through an axios get request Here is what I see in the console log: https://i.stack.imgur.com/ztmf0.png setDappList([response.data.stats]); <div>{setDappList.total}</div> Unfortuna ...