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

In TypeScript, an interface property necessitates another property to be valid

In the scenario where foo is false, how can I designate keys: a, b, c, bar as having an undefined/null/optional type? Put simply, I require these properties to be classified as mandatory only when foo is true. interface ObjectType { foo: boolean; a: nu ...

A guide on updating a MySQL table using a JSON object in Node.js

I have a JSON Object and need to UPDATE a mySQL table without listing all of the keys individually For an INSERT operation, I use the following code: var arrayValue = Object.keys(obj).map(function(key) { return String("'"+obj[key]+"'"); ...

Issue: The --outFile flag only supports 'amd' and 'system' modules

Encountering an issue while trying to compile an Angular project in Visual Studio Code using ng build and then serving it with ng serve Unfortunately, faced the following error message in both cases: The error 'Only 'amd' and 'syste ...

Angular displays X items in each row and column

I've been struggling with this task for the past 2 hours. My goal is to display a set of buttons on the screen, but I'm facing some challenges. The current layout of the buttons doesn't look quite right as they appear cluttered and unevenly ...

Guide on transferring the token and user information from the backend to the front-end

Here is the code from my userservice.ts file export class UserService { BASE_URL = "http://localhost:8082"; constructor(private httpClient:HttpClient) {} public login(loginData:any){ return this.httpClient.post(this.BASE_URL+"/au ...

Ways to verify if the current date exists within a TypeScript date array

I am trying to find a way in typescript to check if the current date is included in a given array of dates. However, even after using the code below, it still returns false even when the current date should be present within the array. Can anyone please pr ...

The process of removing and appending a child element using WebDriverIO

I am trying to use browser.execute in WebDriverIO to remove a child element from a parent element and then append it back later. However, I keep receiving the error message "stale element reference: stale element not found". It is puzzling because keepin ...

Creating a function that is accessible to the entire module

Creating a universal function in a file that is not a module: example.ts: function example() {} You can easily call this function from another file, say test.ts, without needing to import the function from example.ts: test.ts: example(); // calling univ ...

What is the best way to incorporate CSS from node_modules into Vite for production?

I have a TypeScript web application where I need to include CSS files from NPM dependencies in index.html. Here is an example of how it is done: <link rel="stylesheet" type="text/css" href="./node_modules/notyf/notyf.min.css&quo ...

Issues arise when trying to type ChangeEvent in React using Typescript

After spending some time learning React with TypeScript, I encountered a problem. The prop onChangeHandler in my code takes a function to modify properties in formik values. <Formik<FormModel> initialValues={{ favorite: ...

Changing background color during drag and drop in Angular 2: A step-by-step guide

A drag and drop container has been created using Angular 2 typescript. The goal is to alter the background color of the drag & drop container while dragging a file into it. Typescript: @HostListener('dragover', ['$event']) public onDr ...

My Weaviate JavaScript client is not returning anything when I use the ".withAsk" function. What could be the issue?

I recently set up a Weaviate Cloud Cluster using the instructions from the quick start manual. The data has been imported successfully, and the client connection is functioning. For the ask function, I have implemented the following: export async functio ...

Experiencing difficulty creating query files for the apollo-graphql client

I'm currently attempting to learn from the Apollo GraphQL tutorial but I've hit a roadblock while trying to set up the Apollo Client. Upon executing npm run codegen, which resolves to apollo client:codegen --target typescript --watch, I encounter ...

Error Alert: Next.js TypeScript is reporting that the necessary packages are missing from your setup

As I work on developing a basic Next.js website using their TypeScript starter, everything was going smoothly with the 'yarn dev' command. However, out of nowhere, I started encountering an error message whenever I tried to run 'yarn dev&apo ...

Leveraging the power of NestJS in conjunction with Apollo Server version 2

I recently delved into learning nestjs and decided to give this graphql example a try. The issue I encountered is that the example was originally designed for apollo-server version 1, and I'm having difficulty adapting it to work with apollo-server v ...

typescript set parameter conditionally within a function

For my upcoming app, I am working on an API that will utilize Firebase FCM Admin to send messages. Below is the code snippet: import type { NextApiRequest, NextApiResponse } from "next"; import { getMessaging } from "firebase-admin/messaging ...

Extending Error object disrupts `instanceof` validation in TypeScript

Could someone clarify why the error instanceof CustomError part of the code below returns false? class CustomError extends Error {} const error = new CustomError(); console.log(error instanceof Error); // true console.log(error instanceof CustomError); ...

javascript identify dissimilarities within arrays

Working on an Angular 2 application and attempting to identify the difference between two arrays (last seven days and missing dates within the last seven days). Everything works fine when initializing the array through a string, like in example code 1. How ...

Easy steps to bring in type definitions from an npm package using Vite

I am currently developing a package with several ts functions that will be utilized by multiple repositories, including mobile and web applications. In our team, we use vite as our primary build tool, which is also integrated into the repository. Below is ...

Sorting elements in an array based on an 'in' condition in TypeScript

I am currently working with an arrayList that contains employee information such as employeename, grade, and designation. In my view, I have a multiselect component that returns an array of grades like [1,2,3] once we select grade1, grade2, grade3 from the ...