Create a Typescript function that takes in a Class as a parameter

My goal is to create a function that can switch based on the name of a class definition passed in as a parameter.

This function will simplify my testing process by allowing me to generate data for different classes using just one function.

generateMockDataForClass(className: Class, override){
   if(className === Person){ return getPersonMockData(override)}
   if(className === Dog){ return getDogMockData(override)}
...
}

This approach enables me to write tests like:

it('should process a person\'s information', ()=>{
   const p = generateMockDataForClass(Person)
...
})

it('should compare 2 persons', ()=>{
   const p = generateMockDataForClass(Person)
   const p2 = generateMockDataForClass(Person, {name: 'Jane'})
})

However, I have not found a way to make this generic due to the lack of a class type.

Answer №1

Are you seeking just a "newable" type for this scenario?

type Class = {
    new (...args: unknown[]): unknown
    name: string // if necessary
}

This functions as expected:

class Person { person = true }
class Dog { dog = true }

function getMockDataForClass(c: Class, override: Class){
   if(c === Person) { return override}
   if(c === Dog){ return override }
   return c
}

getMockDataForClass(Person, Dog)

Playground


If you desire the second argument to be an instance of the class that is passed in as the first argument, then you must capture the class constructor as a generic parameter. The override is then an instance of that class.

For example:

type Class = {
    new (...args: any[]): unknown
}

class Person {
    constructor(public name: string) {}
}

class Dog {
    constructor(public breed: string) {}
}

function getMockDataForClass<T extends Class>(c: T, override: InstanceType<T>){
  //implementation...
}

getMockDataForClass(Person, {name: 'John'}) // no issues
getMockDataForClass(Dog, {breed: 'Terrier'}) // no issues
getMockDataForClass(Person, {breed: 'Terrier'}) // error

Playground

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

Utilizing a function in an infinite loop within *ngFor along with an asynchronous pipe for an HTTP call

Using a function in an *ngFor statement: @Component({ selector: 'foo-view', template: '<div *ngFor="let foo of loadAll() | async"></div>' }) export class FooComponent { loadAll(): Observable<Foo[]> { return ...

What is the process for loading data with no input provided?

I have come across a situation where my HTML table is populated with various account numbers. https://i.sstatic.net/qJc2E.png When I input the account number 979545130406, the filter works perfectly fine. https://i.sstatic.net/Y4Rwk.png However, the is ...

Tips for building an effective delete function in Angular for eliminating a single record from a table

I've been working on creating a method to delete an employee by their ID, and I've tried various approaches in my VS Code. Unfortunately, all of them have resulted in errors except for this specific method. Whenever I click on the delete button, ...

Implementing a Name Interface in Typescript - A Step-by-Step Guide

export declare const TerminalWidgetOptions; unique symbol; export interface TerminalWidgetOptions { endpoint: Endpoint.Options, id: string, caption: string, label: string destroyTermOnClose: boolean } Upon implementing this interface i ...

`Unable to upload spreadsheet file in xlsx format`

I'm currently working on implementing a feature to export data as xlsx files. I have been successful in exporting CSV and PDF formats, but encountered issues with the xlsx format due to dynamic imports. export const exportToXlsx = async ( gridElemen ...

The absence of the 'classes' property in the MUI component type is causing an issue in Typescript Material UI

Simply put, typescript is giving me a hard time by complaining about the missing property classes on every material-ui component. Essentially, Typescript requires the presence of the classes property in nearly all material-ui components. Here is the error ...

After clicking on the "Delete Rows" button in the table, a white color suddenly fills the background in Angular Material

When the dialog box pops up, you'll see a white background color: https://i.stack.imgur.com/EflOx.png The TypeScript code for this action can be found in config-referrals.component.ts openDialog(action, obj) { this.globalService.configA ...

Troubleshooting the issue of the Delete Service not functioning properly within Angular

ListStore.ts file export class ListstoreComponent implements OnInit { rawlist; name = ''; id = ''; storeid = ""; store: Store; constructor(private api: APIService, private router: Router, private route: ActivatedRoute, pri ...

I have been utilizing ESBuild to compile JavaScript code for browser usage. However, I encountered an issue when trying to import CSS as I received an error message stating "Unexpected '.'". Can anyone provide guidance on how to resolve this issue?

I am currently developing a JavaScript notebook that operates within the browser environment. To compile my code, I have chosen to utilize ESBuild. My primary objective is to enable the handling of CSS imports such as <import 'bulma/css/bulma.css&a ...

Create an array containing elements based on specified type values

How can I create an array that is initialized with values depending on a specific type? type Animals = 'monkey' | 'elephant' | 'lion'; const animalsArray: Array<Animals> = []; // ['monkey', 'elephant&apos ...

What is the best way to declare this massive entity in typescript?

In the process of parsing a file, a large object is returned by the main function. function parse(file){ /* dostuff.. */ return myObject } The order of determining properties is crucial (e.g., "a" must be determined before "b" or the value will be differe ...

Displaying dynamic key-value pairs in each row of an Angular mat-table

I need help displaying a key-value pair data in JSON format dynamically within a table using Angular mat-table. The keys will vary, so there is no set list of keys that will be included in the JSON. This is an example of the data: var data = { "cars" : 2 ...

What could be causing the error with the async pipe: "InvalidPipeArgument: '[object Object],[object Object],' for the pipe 'AsyncPipe'?"

I am working on implementing search functionality in a table using ng-bootstrap. However, I am encountering an error with the async pipe that says "InvalidPipeArgument: '[object Object],[object Object],[object Object],[object Object],[object Object]&a ...

Nested HTTP requests in Angular using RxJS: Triggering component update after completion of the first HTTP request

I have a requirement to make two http requests sequentially. The values retrieved from the first call will be used in the second call. Additionally, I need to update my component once the first http request is completed and also update it once the second ...

Express server crashes when incorporating TypeScript alongside CRA

Summary I recently implemented Typescript into a Create React App (CRA) project, but I keep encountering the following error when attempting to serve the built application: SyntaxError: path\to\root\server\loader.js: Unexpected token, ...

Performing insert operations with multiple repositories in NestJS using TypeORM

I currently have multiple APIs in place that handle CRUD operations, such as: POST /table POST /chair Each API has its own repository instance within their respective Service file. The following is a snippet of the Table's service file: table.servic ...

Picking up Angular component property values within a callback function from Google Charts

Trying to utilize the angular-google-charts library in Angular 13.2, I am working on creating a TreeMap with a customized tooltip feature. The GoogleChartComponent offers an options property called generateTooltip which requires a callback function. My goa ...

Is it better to store data individually in localStorage or combine it into one big string?

When it comes to keeping track of multiple tallies in localStorage, one question arises: Is it more efficient to store and retrieve several small data points individually or as one larger chunk? For example: localStorage.setItem('id1', tally1); ...

Is there a more efficient method for subtracting a set number of months from a date without having to repeat code?

Trying to develop a function that takes the current date as input using: const currDate = new Date() The goal is to pass this value to a function that subtracts a specific number of months from the current date and returns the result in RFC 3399 fo ...

The specified dependency, * core-js/fn/symbol, could not be located

I am in the process of developing a Vue.js application with Vuex and have encountered some errors during the build. I attempted to resolve the issue by installing npm install --save core-js/fn/symbol, but unfortunately, it did not work as expected. https:/ ...