The best approach to structuring a type hierarchy in TypeScript for maximum practicality

I am dealing with an abstract base type and multiple subtypes of it, some of which are abstract on their own and have further subtypes.

My goal is to define polymorphic functions in TypeScript, where some may be abstract while others have default implementations that can be overloaded by specific instances.

How can I best represent this model in TypeScript?

In JavaScript, I typically use classes. Below is a simple example to illustrate what my code might look like. Please focus on the data structure rather than the semantics.

 // Code example

However, translating this code directly into TypeScript poses challenges:

  1. The field name cannot serve as a discriminant for Polygon. A proper discriminant would require introducing a new type PolygonType = Triangle | Square; and using PolygonType instead of Polygon for unknown subtypes.

  2. Using classes limits expressiveness, hindering possibilities such as type level metaprogramming to define precise types.

An alternative approach in TypeScript could involve modeling types using types but sacrificing prototype inheritance polymorphism.

I am curious about other solutions to this common problem and whether one is generally preferred over others.

Answer №1

In this scenario, opting for interfaces over types appears to be the preferable choice.

One key advantage is that interfaces define types, aligning with the desired outcome.

Moreover, an interface serves as an abstract class historically devoid of any implemented methods.

Hence, if treated as a class, it enables polymorphic extensions much like regular classes:

interface Shape {
  area(): number
}
interface Polygon extends Shape {
  toString(): string
}


class Triangle implements Shape {}
class Square implements Polygon {}

Additionally, leveraging a base interface facilitates dependency inversion.

class ShapeDrawer {
  draw(shape: Shape) {} // This method can accept any Shape type, including Polygon or Square.
}

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

Utilizing highcharts to visualize non-linear time data pulled from a CSV file

I am seeking guidance on implementing a simple graph based on data from a CSV file in web development. I lack experience in this area and have struggled to find a suitable example to follow. The CSV file contains data in the format of a unix timestamp, hu ...

Is the TypeScript Callable interface unable to be called?

I am currently in the process of developing a customized version inspired by ts-optchain. The main goal is to create a functionality that produces a duplicate of the original object with specific modifications incorporated without altering the original obj ...

Is there a way to input atypical day and time text into an XDate object?

In order to provide further context; we are dealing with a unique textual representation of time and date that varies significantly and requires conversion into an XDate () object (potentially multiple XDate objects). It's important to clarify that I ...

I am working on an Angular application that includes a dynamic form for an attendance system for employees. I am currently trying to figure out how to generate the JSON data

I have a dynamic form in my reactive attendance system for employees. When I click on submit, I need to generate JSON data like the following: { "user_id": "1", "branch_id": "4", "auth_token": "59a2a9337afb07255257199b03ed6076", "date": "2019- ...

Is there a way to showcase the contents of the angular "tags" object seamlessly?

Is there a way to show the content of the "tags" object using angular? I attempted to achieve it using {{gallery.tags.tag}} but unfortunately, it did not work import {IPhoto} from "./iphoto"; export interface IGallery { galleryId: string; title: ...

Express cannot find routes other than "/" in the request

Currently, I am in the process of developing a web application using the MVC pattern and express framework in node.js. Below is the structure of my project: view project's structure In the file app.js: const express = require("express"); const hbs = ...

Checking the token's validity using the API within the AuthGuard canActivate method in Angular8

As I navigate through certain routes, I need to validate each refresh request. To achieve this, I am utilizing Angular's AuthGuard. The challenge lies in the canActivate method where I aim to perform validation using an online API. The API endpoint i ...

Designing Checkboxes and Radio Buttons

I am seeking a way to customize the appearance of checked and unchecked checkboxes using images without modifying the HTML structure. I would prefer not to add labels, classes, or IDs to the elements. The provided example only works in Webkit browsers, s ...

Steps for locating and relocating an item to the top of a collection in an observable array

I'm new to Rxjs and have a good understanding of pipe, filter, sort, map, etc. However, I am struggling with a particular problem. I need to locate a specific item in the data returned by my observable and move it to the top of the list before display ...

When the size of the mat stepper circle in Angular Material is increased, the position of the line is also adjusting accordingly

Please review my code snippet on StackBlitz Here is a screenshot for reference: https://i.sstatic.net/LJuNC.png ...

Creating a highly innovative server infrastructure tailored for Dojo applications with exceptional features

Recently, I have been using web2py for my projects and have found it incredibly useful in creating RESTful web applications. However, I am now looking to expand my skills in JavaScript by developing a more modern and dynamic client-side application that re ...

Is it possible to apply a formatting filter or pipe dynamically within an *ngFor loop in Angular (versions 2 and 4

Here is the data Object within my component sampleData=[ { "value": "sample value with no formatter", "formatter": null, }, { "value": "1234.5678", "formatter": "number:'3.5-5'", }, { "value": "1.3495", "formatt ...

Validation data not being transmitted in AJAX request

My PHP code is almost working perfectly, but I'm facing an issue with receiving the output of the validate function through AJAX. Can someone help me troubleshoot this problem? $(document).ready(function(){ $("#d").click(function(){ valid ...

Challenge encountered when setting new values to an object depending on its existing values

I am facing an issue with a data object that stores values and their previous values. The keys for the previous values are suffixed with ":previous" e.g. foo and foo:previous. However, I encountered a type error when trying to assign values to the previous ...

Trouble with the JavaScript split function

I am trying to split the data in a specific way. Given a string value like this var str = "[:en]tomato[:ml]തക്കാളി[:]"; I am aiming for the following output: tomato,തക്കാളി. I attempted to achieve this using the code sni ...

`The Importance of Validating Enum Arrays in Typescript Using Class-Validator`

Is there a way to validate an array of enums in a DTO without getting misleading error messages? Here is an example of my DTO: import { IsArray, IsEmail, IsEnum, IsIn, IsNotEmpty, IsString } from "class-validator"; import { UserAction, UserModul ...

Ensure that the context is used to effectively clear any existing data from the previous bar chart

I recently came across a cool codepen demo on this link. Upon clicking the first button followed by the second, the data transitions smoothly. However, there seems to be an issue where when hovering randomly over the bar charts at this source, the value ...

Consistently receiving the identical result even when the checkbox remains unselected

Displaying a Checkbox Input <input id="idCheckbox" name="check" type="checkbox" value="AllValue" style="width: auto; height: auto; font-weight: bolder;" data-bind="checked: idCheckbox" /> The checkbox input will always have the value "AllValue ...

Creating a tooltip for a specific cell within an AG grid react component is a useful customization feature

How can I customize the tooltip for a specific row in my AG Grid? I see that there is a tooltipField available in ColDefs, but I want to provide a custom string instead of using a field value. Is there a way to achieve this customization? ...

In Angular JS, you can seamlessly apply the addClass function to another element by simply hovering over one

Trying to achieve the desired outcome using jQuery but facing issues in an Angular environment. It seems that I might be working outside of the Angular JS scope, and being new to Angular, I'm unsure how to implement this using Angular's scope met ...