TypeScript focuses on checking the type of variables rather than their instance

Is there a way to pass a type (not an instance) as a parameter, with the condition that the type must be an extension of a specific base type?

For example

abstract class Shape {
}

class Circle extends Shape {
}

class Rectangle extends Shape {
}

class NotAShape {
}

class ShapeMangler {
    public mangle(shape: Function): void {
        var _shape = new shape();
        // mangle the shape
    }
}

var mangler = new ShapeMangler();
mangler.mangle(Circle); // should work.
mangler.mangle(NotAShape); // should not work.

I think I might need to substitute shape: Function with something else. Is this achievable in TypeScript?

Note: It's important for TypeScript to acknowledge that shape has a default constructor. In C#, the equivalent would be...

class ShapeMangler
{
    public void Mangle<T>() where T : new(), Shape
    {
        Shape shape = Activator.CreateInstance<T>();
        // mangle the shape
    }
}

Answer №1

Consider two possible approaches:

class ShapeMangler {
    public mangle<T extends typeof Shape>(shape: T): void {
        // manipulate the shape
    }
}

Alternatively,

class ShapeMangler {
    public mangle<T extends Shape>(shape: { new(): T }): void {
        // manipulate the shape
    }
}

Both of these methods are compatible with the compiler:

mangler.mangle(Circle);
mangler.mangle(NotAShape);

In the provided example, your classes are empty, allowing an empty object to match any other structure.
If a property is added, like so:

abstract class Shape {
    dummy: number;
}

Then, using the method with ‘NotAShape’ will result in an error:

mangler.mangle(NotAShape); // Error

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

Utilize a list of Data Transfer Objects to populate a dynamic bar chart in recharts with

I received a BillingSummaryDTO object from a Rest API using Typescript: export interface BillingSummaryDTO { paid?: number, outstanding?: number, pastDue?: number, cancelled?: number, createdAt?: Moment | null, } export async function ...

Avoiding an event from spreading in Angular

I am working on a navigation setup that looks like this: <a (click)="onCustomParameters()"> <app-custom-start-card></app-custom-start-card> </a> When the user clicks on the app-custom-start-card, the onCustomParame ...

Error: There was a problem trying to import the `.d.ts` file

Software Stack Vue version 3.2.19 @vue/test-utils version 2.0.0-rc.15 Typescript version 4.1.6 Issue Description Encountering an error when running the command vue-cli-service test:unit --no-cache. Please refer to the TypeError screenshot (link to Con ...

Having trouble with customizing a selected ListItemButton in Material-UI - need some help with

After reviewing the documentation, I discovered a method to override the styling of the selected class by introducing a new class under .MuiSelected. The implementation looks something like this: const customStyles = makeStyles(() => ({ customizedSele ...

Angular form input set to disabled mode

Visit this link for code <form class="example-form"> <mat-form-field class="example-full-width"gt; <mat-label></mat-label> <input matInput placeholder="Ex. Pizza" [disabled]="filterVal ...

Why do I keep receiving a <prototype> object for each API request?

Currently, I am utilizing JSONPlaceholder in conjunction with Angular as part of my learning process. While I have been following the documentation meticulously and obtaining the correct output, there seems to be an additional element accompanying each obj ...

how to sort arrays in javascript

When it comes to filtering items based on specific criteria like fruit and vegetable filters, what is the most effective method to retrieve items that meet both filter requirements? fruitfilter: [] = [{fruitname: "apple"} , {fruitname: "orange"}] vegeta ...

What are the best techniques for streamlining nested objects with Zod.js?

As a newcomer to zod.js, I have found that the DataSchema function is extremely helpful in verifying API data types and simplifying the API response easily. However, I'm curious if there is a way to streamline the data transformation process for myEx ...

Error message in Visual Studio 2017: Identical name 'URLs' declared twice in

In our Visual Studio 2017 project, we have multiple TypeScript files that define a URLs class. Each file contains different implementations of the class to change site URLs based on the specific use case: customer/urls.ts namespace Portal { export cl ...

Stopping the infinite refresh issue in your React webpack application

Every time I modify the TS file, Webpack keeps refreshing the page without stopping. The console message reads: "@ebpack 5.66.0 compiled successfully" I've searched online and experimented with various plugins, but none of them seem to solve the issu ...

Issues with incorrect source path in Typescript, Gulp, and Sourcemaps configuration

In my nodejs app, the folder structure is as follows: project |-- src/ | |-- controllers/ | | |`-- authorize-controller.ts | |`-- index.ts |--dist/ | |--controllers/ | | |`-- authorize-controller.js | | |`-- authorize-controller.js.map | ...

The observable did not trigger the next() callback

I'm currently working on incorporating a global loading indicator that can be utilized throughout the entire application. I have created an injectable service with show and hide functions: import { Injectable } from '@angular/core'; import ...

The issue with Vuex and Typescript is that when using mutation object payloads, they are consistently undefined

Every time I run my code, the object payload I'm passing as a secondary parameter to my Vuex mutation method ends up being undefined. Both my Vuex and component files are coded in TypeScript. When looking at my index.ts file for my Vuex store (where ...

Debugging a node.js application remotely using SAP Cloud Foundry

Having successfully deployed multiple node.js express services on SAP Cloud Foundry, we have encountered a roadblock in the form of remote debugging. Recognizing that others may be facing similar challenges, we are putting forth a direct inquiry: What is ...

Set values to the inner property of the object

In my configuration file, I have set up nested properties as shown below export class Config { public msalConfig: { auth: { authority: string; clientId: string; validateAuthority: boolean; redirectUri: ...

Utilizing Typescript version 1.5 alongside window.event.ctrlKey

When I need to debug, I occasionally check if the ctrl key is pressed for certain secret actions. This check may be included in any function, not necessarily an event handler itself (it could be a callback or an event handler). In my TypeScript code, I us ...

A Project built with React and TypeScript that includes code written in JavaScript file

Is it an issue when building a React project with Typescript that includes only a few JS components when moving to production? ...

Animation on React child component disappears when re-rendered

My React application utilizes Material UI with a component (let's call it DateSelector) as shown below, slightly altered for demonstration purposes. Material UI provides animations for clicks and interactions within its components. An interesting obs ...

unable to see the new component in the display

Within my app component class, I am attempting to integrate a new component. I have added the selector of this new component to the main class template. `import {CountryCapitalComponent} from "./app.country"; @Component({ selector: 'app-roo ...

Enhancing Type Safety in Typescript through Key/Property Type Guards

Is it possible to create a typeguard that can confirm the existence (or specific type) of a property in an object? For example: Consider an interface Foo: interface Foo { bar: string; baz: number; buzz?: string; } An object of type Foo may ...