A guide on leveraging typeof within function parameters to ensure accurate variances

Let's create a simple class hierarchy and a list of instances. The goal is to filter items from the list of instances based on their class.

There are a couple of challenges:

  • We cannot use the typeof T syntax. How can this be written?
  • We cannot declare T as out variance - we don't want to instantiate anything in the method, just return instances of T. How do we convey this to TypeScript?
class A {
}

class B extends A {
}

class C extends A {
}

function filterByClass<out T extends A>(cls: typeof T, list: A[]): T[]
{
  return list.filter((item) => item instanceof T);
}

Playground Link


Edit:

The solution (by Adrian Kokot) was effective until it was realized that the example was "too simplistic". In reality, constructors have parameters, more like this:

class B extends A {
  constructor(pb: any) {
    super();
  }
}

class C extends A {
  constructor(pc: any) {
    super();
  }
}

Using modified playground provided in the answer, the issue with variance arises:

const a = new A();
const b = new B(1);
const c = new C(1);

const arrC = filterByClass(C, arr); 
Argument of type 'typeof C' is not assignable to parameter of type 'new () => C'.
  Types of construct signatures are incompatible.
    Type 'new (pc: any) => C' is not assignable to type 'new () => C'.

Answer №1

  1. You have the option to define the initial argument as a constructor, allowing you to pass the class name.

  2. To inform TypeScript that an item is an instance of the specified class, you can utilize the is operator as the return type in the filter method.

Potential resolution:

function filterByClass<T extends X>(className: new () => T, array: X[]): T[]
{
  return array.filter((item): item is T => item instanceof className);
}

filterByClass(Y, [new X(), new Y(), new Z()]); // returns Y[];

playground


Solution for update:

If you need to work with classes that have varying constructors, simply include ...args: any[] in the first parameter definition:

function filterByClass<T extends X>(className: new (...args: any[]) => T, array: X[]): T[]
{
  return array.filter((item): item is T => item instanceof className);
}

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

Encountering difficulties importing in Typescript and ts-node node scripts, regardless of configuration or package type

I am facing a challenge with my React Typescript project where multiple files share a similar structure but have differences at certain points. To avoid manually copying and pasting files and making changes, I decided to create a Node script that automates ...

Need help with TypeScript syntax for concatenating strings?

Can you explain the functionality of this TypeScript syntax? export interface Config { readonly name: string readonly buildPath: (data?: Data) => string readonly group: string } export interface Data { id: number account: string group: 'a&a ...

Error encountered: React Typescript does not support the "any" type in a template literal expression

I have been encountering an issue with my slider component in React Typescript. The error message I keep getting is related to the "Invalid type 'any' of template literal expression" specifically at the const fillWidth variable. I am struggling t ...

Sorting List Algorithm

Looking to create an algorithm in Node.js that abides by specific rules. It takes a series of numbers as input and the maximum consecutive number before taking a break. The logic is as follows: The rules : Only one competition per day Competitions are hel ...

Uh-oh! Angular 6 has encountered an unexpected error with template parsing

I am currently working on an Angular application where I have integrated the FormsModule from '@angular/forms' in my app.module.ts. However, despite this, I keep encountering the error message No provider for ControlContainer. Error log: Uncaug ...

I am looking to implement tab navigation for page switching in my project, which is built with react-redux and react-router

Explore the Material-UI Tabs component here Currently, I am implementing a React application with Redux. My goal is to utilize a panelTab from Material UI in order to navigate between different React pages. Whenever a tab is clicked, <TabPanel value ...

Steps for linking HTTP requests in Angular 2 depending on the type of response

My attempt to create an api call from a remote server and then, if an error occurs, make another request from my local server is not working as expected. I am encountering errors and need help to determine if my approach is feasible. Here is the code snip ...

Error encountered with the Angular 2 routing system

Currently, I am facing an issue with my Angular 2 router module. Whenever I try to access the link /city, I encounter an error message saying 'ERROR Error: Uncaught (in promise): Error: Cannot activate an already activated outlet Error: Cannot activat ...

Encountering an undefined value in Angular outside of the subscription

I am facing an issue where I need to use the value from the user outside the subscribe function in order to assign it to my tweet class. However, when I try to print it outside the subscribe function, it shows as undefined. Can anyone provide a solution fo ...

Passing RxJs pipes as a parameter

Is there a way to pass pipes as parameters? For example: var mypipes = [ pipeA(() => { alert("a"); }), pipeB(() => { alert("b"); }) ...

Issues with Rxjs pipe and Angular's Http.get() functionality are causing complications

Working with an Angular 4 Component that interacts with a Service to fetch data is a common scenario. Once the data is retrieved, it often needs to be transformed and filtered before being utilized. The prevailing method for this task is through the use of ...

typescript import { node } from types

Exploring the possibilities with an electron application developed in typescript. The main focus is on finding the appropriate approach for importing an external module. Here is my typescript configuration: { "compilerOptions": { "target": "es6", ...

Error encountered while attempting to globally install TypeScript using npm: "npm ERR! code -13"

Issue with npm error 13 Having trouble installing typescript-g package Error details: - errno: -13, - npm ERR! code: 'EACCES', - npm ERR! syscall: 'symlink', - npm ERR! path: '../lib/node_modules/typescript/bin/tsc', ...

How is it possible to utilize type assertions with literals like `false`?

When working in TypeScript, I came across an interesting observation when compiling the following code: const x = true as false; Surprisingly, this direct assertion is valid, creating a constant x with the value true and type false. This differs from the ...

What are the steps to resolve the "EADDRINUSE: address already in use :::3000" error in an integration test?

While testing my simple endpoint using jest and superTest in my TypeScript project, I encountered the listen EADDRINUSE: address already in use :::3000 error. The file app.ts is responsible for handling express functionalities and it is the one being impo ...

The element you are trying to access, "noUiSlider," does not belong to the type "HTMLElement" and cannot be found

Running into a roadblock here. What mistake am I making? .... /// <reference path="../../../typings/tsd.d.ts" /> var slider:HTMLElement = document.getElementById('slider'); noUiSlider.create(slider, { start: +$input.val(), step: + ...

Obtaining an instance of the CKEditor Editor in TypeScript with CKEditor 4: what's the best way?

Can someone explain how to utilize the CKEDITOR 4 plugin in TypeScript for an Angular 9 application? I am looking to set the configuration through TypeScript (specifically for autogrow) and also implement an INSERT HTML function. I have already imported ...

Arrange an array within an Angular component

I'm in the process of organizing my list-component made with Angular Material. <div style="width:30%;"> <mat-nav-list matSort (matSortChange)="sortData($event)"> <th mat-sort-header="stuff.name">Name</th> ...

Exploring a different approach to utilizing Ant Design Table Columns and ColumnGroups

As per the demo on how Ant Design groups columns, tables from Ant Design are typically set up using the following structure, assuming that you have correctly predefined your columns and data: <Table columns={columns} dataSource={data} // .. ...

How can we include additional types for external npm packages in a React TypeScript project?

Recently, I encountered an issue while using the react-microsoft-login package from npm. I included a button in the children property and received a typescript error stating that "property 'children' does not exist on type 'intrinsicattribut ...