Interface-derived properties

One of the challenges I'm facing is dealing with a time interval encapsulation interface in TypeScript:

export interface TimeBased {

  start_time: Date;
  end_time: Date;
  duration_in_hours: number;
}

To implement this interface, I've created a class called ShiftingTaskDetails:

class ShiftingTaskDetails implements TypeBased, TimeBased {

  type: ShiftingTaskType;
  start_time: Date;
  end_time: Date;
  duration_in_hours: number;

  constructor(type: ShiftingTaskType, start_time: Date, end_time: Date, duration_in_hours: number) {
    this.type              = type;
    this.start_time        = start_time;
    this.end_time          = end_time;
    this.duration_in_hours = Math.abs(end_time.getTime() - start_time.getTime()) / 36e5;
  }
}

The issue arises when I have to redundantly calculate duration_in_hours every time I implement the interface. Is there a way to include derived fields, like duration_in_hours, directly in the interface definition?

I am puzzled about the best practice within the TS community for handling such scenarios. The abstract pattern that typically transforms an interface into a class doesn't seem applicable here. This becomes particularly challenging as I work with multiple interfaces, each requiring its own set of derived fields.

export interface CountBased {
  count: number
}

export interface CountAndPricingBased extends CountBased {

  unit_price: number;
  count: number;
  total_price: number; // total_price should just be unit_price * count 
}

Extending two interfaces with specific derived fields poses a dilemma, especially since extending two abstract classes simultaneously isn't feasible.

Answer №1

To avoid using an Interface in this situation, opt for an abstract class like TimeBased to incorporate the required logic for field calculation directly within the constructor. Subsequently, any derived classes can invoke this logic by calling super within their own constructors.

Answer №2

If you're looking to incorporate implementation in the parent class instead of just outlining its structure, consider defining it as an abstract class:

Unlike an interface, an abstract class can include implementation details for its members.

Since the duration_in_hours is a calculated value based on other properties, it's best implemented as an accessor. Here's an example:

abstract class AbstractTime {
  start_time: Date;
  end_time: Date;

  get duration_in_hours(): number {
    return Math.abs(this.end_time.getTime() - this.start_time.getTime()) / 36e5;
  }
}

class ShiftingTaskDetails extends AbstractTime implements TypeBased {
  constructor(public type: ShiftingTaskType, public start_time: Date, public end_time: Date) {
    super();
  }
}

Additionally, this code snippet utilizes parameter properties to streamline the constructor.

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 could be the reason for the lack of impact when assigning a [dateClass] in mat-calendar?

I've been trying to customize the appearance of specific days in the mat-calendar component from Angular Material, but I'm having trouble getting it to work. I discovered the dateClass property which seemed like the right solution, but no matter ...

Unit Testing Angular: Passing FormGroupDirective into a Function

I am currently writing unit tests for a function that takes a parameter of type FormGroupDirective. I have been able to test most of the logic, but I'm unsure about what to pass as a parameter when calling the resetForm() function. Here is the code sn ...

Is it possible to use multiple schemas for one collection name?

I am currently working on creating different schemas for a single collection, such as User or subUser. I aim to store both User and subuser data in the same collection but with different schemas. Here is an example of my schema file: export const AryaSchem ...

Tips for obtaining type narrowing for a function within a mixed array

In my coding adventure, I have crafted a brilliant match function. This function is designed to take a value along with an array of [case, func] pairs. The value is then compared to each case, and if a match is found, the associated func is executed with t ...

Identify the index of a list item using a custom list created from buttons

When dealing with a dynamically built list like this: <ul id="shortcuts"> <li><input type="checkbox" value="false"/><button>foo</button><button>-</button></li> <li><input type="checkbox" value ...

What are some ways to adjust red and green blocks using CSS?

One question that arises is how to create a version of a webpage where only the yellow block can slide up, while the red and green blocks remain fixed. Currently, the green block is treated with the following CSS: position:sticky; right:0px; top:100px; ...

Creating a mapping strategy from API call to parameters in getStaticPaths

I am attempting to map parameters in Next.js within the context of getStaticPaths, but I am facing issues with it not functioning as expected. The current setup appears to be working without any problems. https://i.stack.imgur.com/LeupH.png The problem a ...

Exploring the use of two different array types in the useState hook with TypeScript

Working on a movie gallery project, I am utilizing an API to download movies and TV series. They are then displayed in a Row component where users can click on thumbnails to open them. The challenge arises with TypeScript, as the useState array can receiv ...

Conceal specific pages within the DataTable without deleting them

Currently, I am facing an issue where the dataTable paginates and removes the DOM pages along with the data. My goal is to extract all the data from the dataTable and convert it to JSON without losing access to the DOM when pagination occurs. I want to m ...

What is the best way to establish a maximum value for variable inputs?

In my Vue form, I have dynamic inputs for issuing shares to shareholders. The user first registers the total amount of shares in the form, then starts issuing this total amount partially by adding dynamic inputs as needed. Finally, the form is submitted. M ...

Use jQuery to open and close HTML tags efficiently

It seems like the task I have at hand may not be as simple as I had hoped, so here I am seeking some reassurance. I am aiming to switch out an image with a closing div, then the image itself, followed by another opening div. Let me illustrate this with a ...

javascript: verify the presence of uppercase and lowercase letters

Can the validation of at least 2 lowercase and 2 uppercase letters be implemented when checking the case? Below is the condition I am currently using. function HasMixedCase(passwd){ if(passwd.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) return true ...

Using the record key as the index for the function argument type

In my current setup, I have : const useFormTransform = <T>( formValues: T, transform: Partial<Record<keyof T, (value: T[keyof T]) => any>>, ) => ... This is how it's used : type Line = { id?: string; fromQuantity: number } ...

Unable to access pathways from a separate source

In my app.component.ts file, I have two router outlets defined, one with the name 'popup': @Component({ selector: 'app-main', template: `<router-outlet></router-outlet> <router-outlet name="popup" ...

What is the method to exhibit the outcome of a promise on a web page within a React component?

In my search for information about promises, I have noticed that most articles provide examples using console.log. However, I am faced with a different scenario. I am working with AWS Athena and I need to display the result on a webpage in my React export. ...

The React Js error message shows an 'Uncaught (in promise)' TypeError that prevents reading an undefined property

Struggling with passing the response from an Ajax request to another function in React. Although I am able to receive the response, I cannot pass it to { this.showBattersData(data); } where I need to render the DOM. It's clear that something is missin ...

Dynamic water filling effect with SVG

I'm trying to create a wipe animation that looks like water filling up inside of a drop shape. Currently, it is a square with a wave animation on top of the drop logo. The wave animation works correctly, but I am struggling to contain it within the dr ...

Why do I keep encountering the error of an undefined variable? Where in my code am I making a mistake

I am struggling to troubleshoot an issue with creating a simple ease scroll effect using the jQuery plugins easing.js and jquery-1.11.0.min.js. $(function(){ //capturing all clicks $("a").click(function(){ // checking for # ...

Learn the process of dynamically populating an HTML table with data using JavaScript and JSON

I have developed a code snippet to dynamically add an HTML table without using jQuery. The code serves as an application from the server to the client, where the client receives a JSON object to parse into a string. Here is how you can add an HTML table ...

Extract specific data points from external API responses on a webpage crafted in HTML

I require assistance on how to extract individual values from an HTML page. I received a response from the PAYU payment gateway team in HTML format, but I need to retrieve specific attribute values related to the transaction details. Below is the response ...