Discovering class methods in typescript

Currently, I am running TypeScript unit tests using Mocha Chai after configuring the compiler options to ts-node.

Within one of my unit tests, I am seeking a way to retrieve all methods from a utility class that I have designed and execute the same set of tests on each method. To provide a clearer picture, I aim to accomplish the following:

UtilityClass.getMethods().forEach(method=>{method(sameInputData)})

Is there a graceful approach to implementing getMethods? Alternatively, are there other strategies available to address this requirement?

Answer №1

Struggling with finding solutions that worked for me, I realized there was a lack of information on achieving the desired outcome without creating an instance.

After some experimentation, here is what I devised:

SomeClass.ts

import { route } from "../../lib/route_decorator";

export class SomeClass {
    index() {
        console.log("here");
    }
}

And in somefile.ts

let ctrl = require("./filepath/filename");
// Since angular exports as `exports.SomeClass = SomeClass;`
ctrl = ctrl[Object.keys(ctrl)[0]];
let ctrlObj = new ctrl();

// Accessing properties from Class without instance
console.log(Reflect.ownKeys(ctrl.prototype));
// Accessing properties from instance
console.log(Reflect.ownKeys(Object.getPrototypeOf(ctrlObj)));

This method successfully outputs:

[ 'constructor', 'index' ]
[ 'constructor', 'index' ]

Answer №2

Keep in mind that TypeScript is essentially a variant of Javascript. The TypeScript compiler translates your code into Javascript.

Therefore, just like you would in regular Javascript, you can list object members in this manner:

UtilityClass myclass = ...;

for (var member in myclass) { /* do something */ }

Going a step further

If you want to ensure you only access directly owned members:

for (var member in myclass) {
  if (myclass.hasOwnProperty(member)) {
    /* do something */
  }
}

Isolating methods

If you specifically wish to isolate methods (functions):

for (var member in myclass) { // For each member of the dictionary
  if (typeof myclass[member] == "function") { // Is it a function?
    if (myclass.hasOwnProperty(member)) { // Not inherited
      // do something...
    }
  }
}

Reflection in TypeScript

These techniques require an instance to operate on, not the class itself. Achieving true Reflection within the realm of OOP is the goal, but Javascript (non-OOP by nature) addresses this concept differently.

Answer №3

Andry's solution is effective for ES3/ES5, but using ES6 and inheritance can lead to some quirky behavior...

Below is a more intricate example demonstrating how to access different types of methods in the case of ES6:

class ParentTest {
    parentFoo = function() {
        // perform actions
    }

    parentBar() {
        // perform actions
    }
}

class Test extends ParentTest {
    foo = function() {
        // perform actions
    }

    bar() {
        // perform actions
    }
}

let instance = new Test();

// Both of these approaches work similarly for every method declared as a property of type "function"
for(let method in instance) {
    console.log(method); // foo, foo2
}
console.log(Object.keys(instance)); // Array [ "parentFoo", "foo" ]

// This approach is suitable for methods within the class
let protoOfTest = Object.getPrototypeOf(instance);
console.log(Object.getOwnPropertyNames(protoOfTest)); // Array [ "constructor", "bar" ] 

// This method is used for accessing methods from the superclass
let protoOfParentTest = Object.getPrototypeOf(protoOfTest);
console.log(Object.getOwnPropertyNames(protoOfParentTest)); // Array [ "constructor", "parentBar" ]

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

Managing errors with Angular2 Observables within the HTML template

The updated Angular's use of observables is a game-changer. No more long chains of .done().fail().always() like in JQuery - NG2 simplifies it all with the | async pipe. However, what happens if something goes wrong while loading data for myObservable? ...

Updating the state on change for an array of objects: A step-by-step guide

In my current scenario, I have a state variable defined as: const [budget, setBudget] = React.useState<{ name: string; budget: number | null }[]>(); My goal is to update this state by using a TextField based on the name and value of each input ...

What is the best method for compressing and decompressing JSON data using PHP?

Just to clarify, I am not attempting to compress in PHP but rather on the client side, and then decompress in PHP. My goal is to compress a JSON array that includes 5 base64 images and some text before sending it to my PHP API. I have experimented with l ...

mentioning a JSON key that includes a period

How can I reference a specific field from the JSON data in Angular? { "elements": [ { "LCSSEASON.IDA2A2": "351453", "LCSSEASON.BRANCHIDITERATIONINFO": "335697" }, { "LCSSEASON.IDA2A2": "353995", "LCSSEASON.BRANCHIDITER ...

Applying background-image in ngStyle results in an undefined value

I have been attempting to incorporate images (retrieved through an API) as the background-image of an element. However, I keep encountering the error message Cannot read property 'url' of undefined, even though the URL is actually being rendered. ...

Looking to incorporate Functional Components in React using the package "@types/react" version "^18.0.17"? Learn how here!

With the removal of the children prop from React.FC type, what is the new approach for typing components? ...

Using the concat operator along with the if statement in Angular to make sequential requests based on certain conditions

Managing multiple HTTP requests in a specific order is crucial for my event. To achieve this, I am utilizing the concat operator from rxjs. For instance, upon receiving data from the first request, I update local variables accordingly and proceed to the ne ...

Steps for running a TypeScript project as a child process within a JavaScript project

I am facing an issue with integrating my Electron app, written mainly in JavaScript, with an Express server project built in TypeScript. When I attempt to create a child process of the TypeScript project within my electron.js file, I encounter TypeScript e ...

Secure Your Passwords with Encryption in NestJS using @nestjs/mongoose before saving them

Seeking to encrypt passwords before saving using @nestjs/mongoose. Came across examples written in pseudocode like this: UsersSchema.pre('save', (next: any) => { if (!this.isModified('password')) return next(); this.password = en ...

The key to subscribing only once to an element from AsyncSubject in the consumer pattern

When working with rxjs5, I encountered a situation where I needed to subscribe to an AsyncSubject multiple times, but only one subscriber should be able to receive the next() event. Any additional subscribers (if still active) should automatically receive ...

How can I only accept one of two specific function signatures in Typescript and reject any others?

Looking for an answer from the community on Typescript, require either of two function signatures In my code, I am handling a callback where I need to either pass an error or leave the first argument as undefined and pass data as the second argument. To ...

Retrieve the chosen item to automatically fill in the input fields using Ionic 2 and Angular

My goal is to create a dropdown menu populated with a list of items, and when a product is selected, its price should automatically appear in the quantity field. <ion-item> <ion-label>Item</ion-label> <ion-select (ionChange)="getP ...

A guide on obtaining the date format according to locale using Intl.DateTimeFormat within JavaScript

Can someone assist me in obtaining the standard date format (such as MM/DD/YYYY) based on a specified local id? The code snippet provided below is not returning the desired format. Any guidance on how to achieve this would be greatly appreciated. var da ...

Typescript's Patch<T> type enforces strictness within the codebase

There have been instances where I needed to 'patch' an object T using Object.assign(). For instance, when propagating changes you might modify a stateful object that other code references (common in reactive programming like MobX or Vue). It&ap ...

Dealing with an AWS S3 bucket file not found error: A comprehensive guide

My image route uses a controller like this: public getImage(request: Request, response: Response): Response { try { const key = request.params.key; const read = getFileStream(key); return read.pipe(response); } catch (error ...

Choose a specific div element from a collection of dynamically generated divs in Angular

I have been working on a code to dynamically generate div elements using the *ngFor directive. Here is what I have so far: <div *ngFor = "let item of Items"> <p>Item : {{item}} </p> </div> The challenge I encountered is that w ...

Adding a baseURI to the image src in Angular 5 is causing issues with dynamically loading images

I am currently working on Angular 5.2.1 and I am facing an issue with loading an image from a server using its source URL. Here is the HTML code: <img #image [src]="cover" class="img-fluid" alt="NO image"> And here is the TypeScript code in image- ...

typescript: best practices for typing key and value parameters in the forEach loop of Object.entries()

I have a specific object with key/value pairs that I need to iterate over using the entries() method of Object followed by a forEach() method of Array. However, I'm struggling to understand how to avoid a typescript error in this situation: type objTy ...

Navigating through an interface array using *ngFor in TypeScript

After successfully implementing an interface to retrieve data from a service class, I encountered an issue when attempting to iterate through the FilteredSubject interface array. Despite using console.log, I was unable to achieve the desired outcome. You ...

Issue encountered when using await in Tensorflow.js sample code with TypeScript

After going through the official tensorflow.js documentation, I attempted to test this example using typescript with tensorflow.js While trying to execute the code snippet provided in the tensorflow.js documentation, I encountered an error related to the ...