List out all the classes that implement an interface in Typescript

Greetings to all TypeScript enthusiasts!

Here's a challenge I want to tackle: I aim to establish an interface -- let's name it IShape -- and define several classes (Rectangle, Circle, Triangle) that adhere to the IShape interface.

Let's say that IShape includes a method called GetName which provides a string representing the shape's name. For now, let's assume that each class implementing GetName returns a static string (e.g.: "Rectangle", "Round object", "Pointed figure"). Additionally, let's envision that IShape incorporates the Draw method.

During runtime, my objective is to compile and display a list of all classes that implement IShape, thereby allowing users to select a shape from a drop-down menu. Upon selection, the system should invoke the selected shape's Draw method.

However, here's the twist: in the future, I wish to introduce new classes that conform to the IShape interface (let's call them Square and Oval). The next time I execute the code, these new classes should automatically appear in the drop-down menu without requiring extensive modifications to the existing code base.

How can this be achieved in TypeScript?

The ultimate goal is to create a flexible system that empowers team members to expand upon my code by introducing new shapes that adhere to the established interface, eliminating the need for a hardcoded list of accepted shapes.

I appreciate any assistance you can provide. Thank you.

Answer №1

In my approach to coding this, I will outline the steps I would take while acknowledging that it is based on personal preferences, which may not align with yours.

Firstly, I utilize standard ES6 import and export. All my shape classes reside in a single folder within my codebase along with an index.ts file that handles exports for the entire directory. This results in a structure similar to:

|-- src/
|    |-- shapes/
|    |    |-- index.ts
|    |    |-- IShape.ts
|    |    |-- Rectangle.ts
|    |    |-- Circle.ts
|    |    |-- Triangle.ts
|    |
|    |-- ShapeList.ts

The content of IShape.ts typically looks like:

export interface IShape {
  draw(): void;
}

Within Rectangle.ts, Circle.ts, Triangle.ts, you can find code such as:

import { IShape } from './IShape';

export class Circle implements IShape {
  static getName: () => 'Circle';
  draw(): void {
    //...
  }
}

In index.ts, I import the individual shape classes and export them as an array:

import { Circle } from './Circle';
import { Rectangle } from './Rectangle';
import { Triangle } from './Triangle';

export default [
  Circle,
  Rectangle,
  Triangle,
];

Lastly, in ShapeList.ts, I simply make use of the exported shapes to create my ShapeList:

import shapes from './shapes';

export class ShapeList {
  getItems() {
    return shapes.map(shape => ({
      label: shape.getName(),
      action: () => new shape(), // Simple factory method for creation when selected
    }));
  }

  // ... Rest of the class
}

This configuration helps streamline the process of adding new shapes:

  1. Write the code for the new shape class
  2. Ensure proper exporting

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

What is the process for performing interpolation in Angular version 8?

In my Angular project, I have 2 components working together. Component A sends an id using the following code snippet: <a [routerLink]="['/numbersbyareacode', element.id]"> {{element.title}} </a> Upon navigating to Component B, ...

I'm interested in developing a feature that monitors a specific attribute and triggers a function once that attribute hits the value of 100

I am working on a function that will refresh the view once the percentage changes reaches 100: The value is stored in this variable: this.uploadPercent = task.percentageChanges(); This is the function I plan to implement : refreshView(){ Once this.uplo ...

How can Angular components that are not directly related subscribe to and receive changes using a declarative approach?

Here's the issue at hand: I'm facing a problem with my Dashboard component. The Dashboard consists of a Sidebar and Navbar as child components. On the Sidebar, I have applied a custom permission directive to the links to determine if the user ha ...

Verify whether a component is a React.ReactElement<any> instance within a child mapping operation

I am facing a challenge with a component that loops through children and wraps them in a div. I want to exclude certain elements from this process, but I am struggling to determine if the child is a ReactElement or not (React.ReactChild can be a string or ...

Angular: Generating a fresh instance of an object monthly

My goal is to create an object called "Activity" in Angular 8, which will automatically generate an activity for each month upon creation. For example: export class Activity { activityID = string; activityName = string; startDate = Date ...

Error: Module not found '!raw-loader!@types/lodash/common/array.d.ts' or its type declarations are missing

I encountered a typescript error while building my NEXT JS application. The error message was: Type error: Cannot find module '!raw-loader!@types/lodash/common/array.d.ts' Below is the content of my tsConfig.json file: { "compilerOptions& ...

Exporting a class from an index.ts file may result in a problem where the injected constructor is

Utilizing an index.ts file to manage exports, following the guidelines outlined in the Angular 2 style guide (https://github.com/mgechev/angular2-style-guide/blob/master/old/README.md#directory-structure), has been successful throughout my application deve ...

Angular: Issue with subscribed variable visibility on screen

I am currently developing user management functionality. When a button is clicked, the goal is to save a new user and display an incoming password stored in the system. Below is a snippet of my code: onClick() { /*Code to populate the newUser variable from ...

Inheritance from WebElement in WebdriverIO: A Beginner's Guide

I am seeking a solution to extend the functionality of the WebElement object returned by webdriverio, without resorting to monkey-patching and with TypeScript type support for autocompletion. Is it possible to achieve this in any way? class CustomCheckb ...

Typescript fails to identify the parameter type of callbacks

I am facing a challenge with the function below and its callback type: type Callbacks = { onSuccess: (a: string) => void; }; function myFunction(event: string, ...args: [...any, Callbacks]) { } The function works correctly except for one issue - ...

Getting event properties in a React component using the rest operator: A comprehensive guide

Can someone please assist me? I am new to TypeScript and struggling with how to use event props in my component. I have defined two props and need all my events as rest props. I encountered an error when trying to use my component with onClick event. The ...

Simplify a function by lowering its cyclomatic complexity

This particular function is designed to determine whether a specific cell on a scrabble board qualifies as a double letter bonus spot. With a cyclomatic complexity of 23, it exceeds the recommended threshold of 20. Despite this, I am unsure of an alterna ...

Create a full type by combining intersecting types

I have multiple complex types that are composed of various intersecting types. I am looking to extract these types into their final compiled form, as it would be useful for determining the best way to refactor them. For example, consider the following: ty ...

create an instance of the class provided as an argument

I wanted to design a system for creating different types of Plants (inspired by plants vs zombies) in an organized way. To simplify the addition of new plant Types, I aimed to make the cost and damage of each plant static so it could be set once for all Pl ...

Having trouble getting anime.js to function properly in an Ionic 3 project?

I have been attempting to incorporate anime.js into my Ionic 3 project, but I keep encountering an error when using the function anime({}) in the .ts file. Error: Uncaught (in promise): TypeError: __webpack_require__.i(...) is not a function TypeError: _ ...

Identify all the CHECKBOX elements that are visible and not concealed

On my page, I have various checkboxes - some with hidden=true and others with hidden=false attributes. Despite trying to use a selector or jQuery to locate checkboxes with the hidden property, I am still facing some challenges. My goal is to differentiate ...

I'm facing an issue with SSRProvider in my NextJs application

My application is developed using NextJs and Typescript, utilizing the react-bootstrap library for creating components. I am facing an issue where I keep receiving an error message stating that When server rendering, you must wrap your application in an &l ...

The issue arises when attempting to invoke a method from a global mixin in a Vue3 TypeScript component

I've been working on this challenge for the past week, and I would appreciate any help or insights from those who may have experience in this area. Currently, I am in the process of converting vue2-based code to vue3 for a new project. Instead of usi ...

Is there any advice for resolving the issue "In order to execute the serve command, you must be in an Angular project, but the project definition cannot be located"?

Are there any suggestions for resolving the error message "The serve command requires to be run in an Angular project, but a project definition could not be found."? PS C:\angular\pro\toitsu-view> ng serve The serve command requires to be ...

Looking for a solution to the error message: "X is not able to be assigned to the type 'IntrinsicAttributes & Props'"

Greetings everyone! I need some assistance in setting up single sign-on authentication using React, Azure AD, and TypeScript. I'm encountering a type error in my render file and I'm unsure of how to resolve it. Below is the specific error message ...