What is the best way to limit a generic argument to only those that are subclasses of a class/constructor that implements a particular interface

I have a function that needs to accept a generic argument type which is constrained to implement a specific interface. I achieved this by defining the interface, an abstract stub class implementing the interface, and using the typeof operator to reference the abstract stub class.

Below is a code sample demonstrating the issue and solution:

interface Interface {
    get FooVal(): any;
}
abstract class StubClass implements Interface {
    abstract get FooVal(): any;
}
function Foo<T extends typeof StubClass>( bar: T ) { }
function Bar<T extends        Interface>( bar: T ) { }

class UserClass implements Interface {
    get FooVal() { return null; }
}
Foo( UserClass ); // No Errors/Warnings
Bar( UserClass ); // Argument of type 'typeof UserClass' is not assignable to parameter of type 'Interface'.

Is there a way to achieve this without defining the abstract stub class?

Answer №1

If you are looking for a constructable type, consider the following:

interface Interface { get FooVal(): any; }
type InterfaceConstructor = { new(): Interface }

The InterfaceConstructor type is designed to output an object of type Interface upon instantiation.

With this setup, you can now utilize the code below:

function bar<T extends InterfaceConstructor>( bar: T ) { }

class UserClass implements Interface {
    get FooVal() { return null; }
}

bar( UserClass ); // this will work fine

Take a look at 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

Function 'Once' in Typescript with Generics

Currently, I am utilizing a feature called Once() from FP. In TypeScript, I need to define the types for this function but have been struggling with the implementation. Here's what I have attempted so far: const once = <T, U>(fn: (arg: T) => ...

I am experiencing issues with the search feature in angular and node.js that is not functioning properly

Need assistance with debugging this code. I am currently working on adding search functionality to my Angular web page. However, when testing the code in Postman, I keep receiving the message "NO USER FOUND WITH USERNAME: undefined". Additionally, on the w ...

Is it possible for the Angular Router to display URLs directly entered into the address bar of the browser

My current router configuration is as follows: const routes: Routes = [ { path: 'topic/:id', component: TopicComponent, resolve: { topic: TopicResolverService } }, { path: '', pathMatch: 'full', ...

What is the best way to obtain a signed cookie in aws-sdk-js-v3?

I am looking to utilize signed cookies for accessing private content stored on S3 using CloudFront for CDN. I am struggling to identify the appropriate commands to generate signed cookies in aws-sdk-js-v3. According to the updated SDK documentation, it sh ...

Angular TextInput Components don't seem to function properly when dealing with arrays

I am trying to create a collection of text input components with values stored in an array. However, when using the following code, the values seem to be placed incorrectly in the array and I cannot identify the bug. <table> <tr *ngFor="let opt ...

Change TypeScript React calculator button to a different type

I am currently troubleshooting my TypeScript conversion for this calculator application. I defined a type called ButtonProps, but I am uncertain about setting the handleClick or children to anything other than 'any'. Furthermore, ...

Setting up next-i18next with NextJS and Typescript

While using the next-i18next library in a NextJS and Typescript project, I came across an issue mentioned at the end of this post. Can anyone provide guidance on how to resolve it? I have shared the code snippets from the files where I have implemented the ...

Tips for keeping your cool when a listener is suggesting changing it to a const variable

How can I output the isChecked value to the parent component? This value indicates whether the checkbox is clicked or not. Unfortunately, changing it to const is not an option due to an assignment below. My linter is suggesting that I change it to const, ...

What is the best way to display a loading state while waiting for all Firebase data requests to be fully processed?

Hey there! I'm looking for some advice on how to display a loading indicator like this: https://i.sstatic.net/7luvR.gif while waiting for my Firebase data to load completely. I attempted to use <div *ngIf="!listOfFoodObject"> <img [src ...

Retrieve the runtime configuration object or file using Jest

Is there a way to access the Jest runtime config object or file path? I wanted to utilize runtime config properties in my custom matchers. // ./jest.config.js const path = require("path"); module.exports = { prop1: "foo", prop2: "bar" }; // my-custo ...

How can you ensure a code snippet in JavaScript runs only a single time?

I have a scenario where I need to dynamically save my .env content from the AWS secrets manager, but I only want to do this once when the server starts. What would be the best approach for this situation? My project is utilizing TypeScript: getSecrets(&qu ...

When transmitting data from NodeJS, BackBlaze images may become corrupted

I have been facing a challenge in my React Native app where I am attempting to capture an image and then post it to my NodeJS server. From there, I aim to upload the image to BackBlaze after converting it into a Buffer. However, every time I successfully u ...

What does it signify when it is stated that "it is not a descendant of the indexer"?

Currently, I am diving into Typescript with the help of this informative guide on indexer types. There is a specific piece of code that has me puzzled: interface NumberDictionary { [index: string]: number; length: number; // okay, length shoul ...

How can I create and assign types dynamically in TypeScript?

I'm working on creating an SX styling file with a style object of type SXPropsTypes. In another file, I'm having trouble accessing the style properties because the autocomplete isn't suggesting the keys of my style object. style.ts import { ...

React did not allow the duplicate image to be uploaded again

I've implemented a piece of code allowing users to upload images to the react-easy-crop package. There's also an "x" button that enables them to remove the image and upload another one. However, I'm currently facing an issue where users are ...

Transferring information from a service to a parent component, and subsequently passing it to a child component

Hello everyone, I am a beginner with Angular and I seem to have run into an issue that I can't figure out. In my parent component, I am attempting to pass the weekly variable to my child component but it doesn't seem to be working as expected. H ...

Is there a way to determine the height of the ion-footer?

Is there a way to obtain the height of the ion-footer element in Ionic2? I want to calculate the initial window height minus the ion-footer height, but I am currently only able to get the overall window height. I'm not interested in retrieving the ...

Monitoring modifications in elements within an array using Angular2

Currently using Angular 2 and typescript, I have an array in which I am utilizing DoCheck and IterableDiffer to monitor any changes. While I receive notifications when the array itself is modified, I do not get notified if a property within one of the obje ...

What should I do about typescript and ES6?

An error occurred while running my code: [0] app/components/people/details/PersonDetailComponent.ts(27,35): error TS2339: Property 'person' is missing from type '{}'. Here is the code snippet in question: export class PersonDeta ...

Utilizing External Libraries Added Through <script> Tags in React

My goal is to develop a Facebook Instant HTML5 application in React. Following their Quick Start guide, Facebook requires the installation of their SDK using a script tag: <script src="https://connect.facebook.net/en_US/fbinstant.6.3.js"></scrip ...