Using Typescript generics to enhance arrays

I am looking to extend a generic list of Array that has been previously extended from my class. How can I accomplish this in the correct way?

export interface DeliveryMethod {
  readonly id: string;
  readonly company: string;
  readonly cost: number;
  readonly threshold: number;
  readonly intervals: Array<Interval>;
  readonly paymentMethods: Array<PaymentMethod>;
}

export interface Delivery {
  selected: SelectedDelivery;
  available: { [key : string] : Array<T extends DeliveryMethod>;};
}

The error 'Cannot find name 'T'.ts(2304)' is showing up.

available: { [key : string] : Array<T extends DeliveryMethod>; };

One solution could look like this:

const Delivery = {
   selected :{/*data inside*/},
   available:{
      pickup: [<Pickup>{},<Pickup>{}],
      courier: [<Courier>{},<Courier>{}]  
   }
}

Answer №1

The response by @aopanasenko is satisfactory. To further enhance it, I propose a solution for addressing the issue of multiple specifications.

If the characteristics of the available are limited and remain constant, one approach is to explicitly list them within the Delivery interface:

interface Delivery<T extends DeliveryMethod, U extends DeliveryMethod> {
  available: { [key : string] : Array<T | U>};
};

This allows you to define the delivery object as follows:

const delivery: Delivery<Pickup, Courier>

In situations where the properties may not be known in advance, a method to associate property names with TypeScript types is necessary. For this purpose, an available object can be utilized for mapping:

interface Delivery {
  available: { [key: string]: Array<DeliveryMethod> | null };
};

const delivery: Delivery = {
  available: {}
}

const available: {
  pickup: Pickup[] | null,
  courier: Courier[] | null
} = {
  pickup: null,
  courier: null
};

delivery.available = { ...delivery.available, ...available };

This approach ensures proper type validation. The inclusion of | null serves as an example and can be omitted if necessary.

Answer №2

Update

According to @AndreaSimoneCosta's suggestion in the comment, the code snippet below should work:

export interface DeliveryMethod {
  readonly id: string;
  readonly company: string;
  readonly cost: number;
  readonly threshold: number;
  readonly intervals: Array<Interval>;
  readonly paymentMethods: Array<PaymentMethod>;
};

export interface Delivery<T extends DeliveryMethod = DeliveryMethod> {
  selected: SelectedDelivery;
  available: { 
    [key : string] : Array<T>
  };
};

It is important to define the generic type parameter list within angle brackets after the name of the Delivery interface:

export interface DeliveryMethod {
  readonly id: string;
  readonly company: string;
  readonly cost: number;
  readonly threshold: number;
  readonly intervals: Array<Interval>;
  readonly paymentMethods: Array<PaymentMethod>;
};

export interface Delivery<T extends DeliveryMethod> {
  selected: SelectedDelivery;
  available: { 
    [key : string] : Array<T>
  };
};

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 best way to execute a specific set of unit tests in Gulp-Angular using Karma?

In the midst of my AngularJS 1.4 project, fashioned through the Gulp-Angular yeoman generator, I find myself facing a dilemma. With karma and gulp settings already in place, executing gulp test runs all *.spec.js files within the project. However, my desir ...

Does the webpack style loader load only application-specific CSS, or is it designed to handle all CSS files?

I am in the process of improving the modularity of my front-end design by delving into webpack. This tool provides a style loader, which enables you to import a css file and inject it into the document like this: require("style/url!file!./file.css"); // = ...

Removing leading zeros from numeric strings in JSON data

I am facing an issue with my jQuery-based JavaScript code that is making an Ajax call to a PHP function. updatemarkers.xhr = $.post( ih.url("/AjaxSearch/map_markers/"), params).done( function(json) { <stuff> } The PHP function returns the follo ...

monitor the location of a div within a textarea

My question revolves around a textarea that is linked to a draggable div through the following code: $('#content').children().draggable({ drag : function () { $('#textarea').text("left:" +($(this).position( ...

What is the proper way to display the initial content of the menu?

I am currently working on a website design for an upcoming festival. The festival spans over three days, so I have created buttons to navigate and load the content for each day separately. Is there a way for me to make the content for the first day di ...

Does LABJS include a feature for executing a callback function in the event of a timeout during loading?

When using LabJS to asynchronously load scripts with a chain of dependencies, if one of the scripts breaks (due to download failure or connection timeout), it seems that the remaining scripts in the chain will not be executed. Is there a way to define a ...

Can you explain how to achieve auto-assigning arrays in JavaScript similar to the PHP feature?

I'm seeking a way to update a JavaScript array automatically, without specifying a key as a number or string. The value should simply take the next available numeric key in the array. In PHP, you can achieve this using: <? myarray = array(); mya ...

Adjusting characteristics in Angular dynamically through JSON

Having trouble changing the value of [icon]="reactAtom" to use a JSON value? Need assistance in updating the [icon] value based on the 'featureItem' received from the parent component. HTML <div> <fa-icon [icon]="reactAtom" class="i ...

what sets apart parseint from minus

Typically, my approach for parsing numbers in JavaScript involves the following code snippet: var x = "99" var xNumber = x - 0 as opposed to using: var xNumber = parseInt(x) I am curious to know if there are any potential issues with this method in ter ...

Tips for stopping the submission of a form

My current form includes ajax calls: <form method="post" action="?slt=Sbmt" onsubmit="return validateForm()" id="reportform" enctype="multipart/form-data"> <div id="evaluation1"> <h2>Rate Technical Skills</h2> <table class= ...

Retrieving component attributes using jQuery or alternate event handlers

In my Angular2 component, I am facing an issue with using vis.js (or jQuery) click events. Despite successfully displaying my graph and catching click events, I encounter a problem where I lose access to my component's properties within the context of ...

What steps should be taken to fix the error "Warning: Encountered multiple children with the same key" in React.js?

I'm having trouble fetching and displaying data from an API. Whenever I attempt to show the data, I encounter the following error message: Alert: Found two children using the same key, [object Object]. Keys must be unique so that components can pro ...

Can anyone explain why the Splice function is removing the element at index 1 instead of index 0 as I specified?

selectedItems= [5,47] if(this.selectedItems.length > 1) { this.selectedItems= this.selectedItems.splice(0,1); } I am attempting to remove the element at index 0 which is 5 but unexpectedly it deletes the element at index ...

Is my understanding of HTML and JavaScript code accurate?

Explaining lines of code to my class for homework has been a challenge. I tried my best to break it down, but I'm not entirely confident in my accuracy. My grade depends on being 100% precise and detailed. <!DOCTYPE html> The first command dec ...

Effortless method to handle package.json configurations

Is there a better approach for seamlessly transitioning between using npm link and git, or another solution that caters well to both front end and back end developers? The dilemma I'm facing revolves around developing a website that utilizes multiple ...

The "rest" variable is automatically assigned the type of "any" because it lacks a specified type and is used within its own initializer

Attempting to set up a private route using react router 4 and Typescript. Check out the code I'm working with: type CustomRouteProps<T> = T & { component: any, authRequired: boolean }; function PrivateRoute({ component: Component, authRequ ...

The index.js file from Heroku NodeJS is being delivered as a response instead of being run

I have a GitHub repository that functions properly on my local machine using 'npm start' or 'heroku local web', but when deployed to Heroku, it only displays the contents of the dist/index.js file instead of executing it. This applicat ...

Dropdown Placement Based on Button Click

Looking to create an interactive dropdown menu with the Alloy UI Dropdown Component that appears when a user clicks on one of four buttons. The goal is for this dropdown to be positioned to the left of the clicked button. var toolsDropdown = new Y.Dropdow ...

Transform the object into a function that returns the object while still maintaining the casting

I have this item: const five: { quantity: number } = { quantity: 5, } I would like to transform it into a function that yields the same item, like this: const five = () => ({quantity: 5}) Is there a way for me to reuse the casting to ensure the re ...

Potential issue with Lodash's _.once function: the possibility of a race condition

Here's an example of code that demonstrates a scenario: const fetch = _.once(myRealFetch) const queue = new PQueue({concurrency: 1000}); queue.add(function() { const result = fetch() // Rest of the code ... }) queue.add(function() { const resul ...