What is the process for creating a new Object based on an interface in Typescript?

I am dealing with an interface that looks like this:

interface Response {
    items: {
        productId: string;
        productName: string;
        price: number;
    }[]
}

interface APIResponse {
    items: {
        productId: string;
        productName: string;
        price: number;
        factoryId: string,
        status: number,
        category: number,
        priority: number
    }[]
}

Currently, I have a function that returns Response:

async function getList(): promise<Response> {
    // data.htw.cart.list return APIResponse
    const response = await data.htw.cart.list(postJson)
    return response
}

However, the data.htw.cart.list function returns an APIResponse, which means I receive excessive data that I do not need.

Each time I have to manually filter out unnecessary information like this:

return {
  items: response.items.map(item => {
    return {
      productId: item.productId,
      productName: item.productName,
      price: item.price
    }
  })
}

Is there a tool available that can automatically trim down the APIResponse to match the structure of Response?

Two important points to consider:

  1. The structure of APIResponse always includes that of Response
  2. The key names in Response are the same as those in APIResponse

Answer №1

To establish clear connections between your different types, it is best to define the appropriate relationships.

interface Product {
  productId: string
  productName: string
  price: number
}

interface APIProduct extends Product {
  factoryId: string,
  status: number,
  category: number,
  priority: number
}

interface ResponseData {
  products: Product[]
}

interface APIResponseData extends ResponseData {
  products: APIProduct[]
}

// Now APIResponseData can be assigned to ResponseData
let data: ResponseData = ...;
let apiData: APIResponseData = ...;
data = apiData;

// You can also assign an array of APIProducts to an array of Products, 
// but you will lose type information while keeping the fields intact
const apiProducts: APIProduct[] = [...];
const products: Product[] = apiProducts;

This approach helps the compiler understand the relationships between your types more effectively.

If you need to physically remove unnecessary fields, using the .map method as shown in your question is a good solution. Alternatively, you may consider utilizing a JavaScript library like lodash/pluck, even though this may negate the benefits of static type checking.

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

Differentiating the angular distinction between setting a variable with ng-click and invoking a function

I've encountered a situation like this before. Let's assume the controller has these variables: $scope.valueArr = ['Hello', 'No', 'Yes']; $scope.myValue = 'Hello'; And there is an ng-repeat as follows: ...

Error: The function 'stepUp' was invoked on an object lacking the HTMLInputElement interface during an AJAX request

It's always frustrating to have to ask a question that has already been asked, but I'm having trouble finding a solution that works for me. My issue involves retrieving the value of an input and sending it via AJAX. $("#cell_number").on("change" ...

Execute Javascript Code Once Directive Has Finished Rendering the DOM for ShareThis

Within my Angular (1.3) application, I have a list of records being displayed using ng-repeat. The template includes a directive that contains ShareThis controls from ShareThis, which are activated once the DOM is loaded. Upon the initial load of the app, ...

At what point are DOMs erased from memory?

Recently, I've been working on an application that involves continuous creation and removal of DOM elements. One thing I noticed is that the process memory for the browser tab keeps increasing even though the javascript heap memory remains steady. To ...

Adding Bootstrap component via ajax request

I'm facing an issue with injecting a Bootstrap component using ajax. I usually include a select element like this: <select class="selectpicker" data-width="75%"> Most of the HTML code is generated dynamically through javascript, which you can ...

Having trouble with VSCode/tsconfig path configurations, as the files are being fetched but still receiving a "Module not found" error in the editor

Since I began working on this project, I've been encountering a peculiar issue. When importing modules and files in my Angular components/classes using import, I face an error in VSCode when the paths use the base path symbol @. Strangely enough, desp ...

Using JavaScript to locate and emphasize specific words within a text, whether they are scattered or adjacent

I need help finding a JavaScript code for searching words in a text using a form and a search button. I found one that works for multiple words in a row, but it doesn't work if the words are mixed up. What changes should be made to fix this issue? An ...

Displaying a Dynamic Loading Animation While Making an AJAX Call with jQuery

When a user clicks on the active status button, it should switch to inactive with a red color, and vice versa. Currently, I can update my status in the backend, but I have to refresh the page to see the changes every time! My requirement is that during t ...

When the Component is mounted, it triggers a GET request and passes the response as a prop to the child component. What occurs if I enter a URL that directly accesses the child

Consider a scenario where there are 2 URLs: website.com/Overview website.com/Overview/City When website.com/Overview is accessed, the component shown is Overview, while accessing website.com/Overview/City reveals the City component. An issue arises when ...

Having trouble with the DataTables jQuery plugin? Seeing a blank page instead of the expected results?

I've been trying to set up the Datatables jquery plugin for my HTML table but it's not working as expected. I have linked to the Datatables CDN for CSS styling and script, along with Google's hosted jQuery plugin. Additionally, I have a loca ...

Tips for updating the secure route with TypeScript and React-Router versions 4, 5, or 6

I've been attempting to create a <PrivateRoute> based on the example in the react-router documentation using TypeScript. Can someone provide assistance? The PrivateRoute from the react-router documentation: const PrivateRoute = ({ component: Co ...

Challenge with setting asynchronous default value in React Material UI Autocomplete

Utilizing the 'Material UI' Autocomplete component to show a dropdown in my form. Whenever the user wishes to edit an item, the dropdown should autofill with the corresponding value fetched from the database. Attempting to simulate this scenario ...

The tablet is having trouble playing the mp3 audio file

When clicking on an mp3 audio file, I want the previous file to continue playing along with the new one. While this works perfectly on browsers with Windows machines, there seems to be an issue when using a tablet. The second mp3 stops playing when I clic ...

Is there a more efficient way to avoid duplicating JS blocks in multiple locations?

I'm currently working on a dual navigation menu/map feature where clicking on specific locations will display a new panel while hiding the previously viewed one. I've also added a map hover effect. You can check out my progress on JSFiddle. As I ...

Transform the binary image data sent by the server into an <img> element without using base64 encoding

It's been a challenge trying to find a reliable method for adding custom request headers to img src, so I'm experimenting with manually downloading the image using ajax. Here is an example of the code I am working on: const load = async () => ...

Which comes first in AngularJS: ng-include or ng-repeat?

What is the outcome if I have a template containing ng-repeat and include it using ng-include? Will the included template have the completed ng-repeat, or will it be included without the ng-repeat being complete (and then completed after inclusion)? ...

The size of the cursor varies depending on the line it's placed on

I have a content editable div where three lines are separated by BR tags. When I click on the second line, the cursor becomes bigger than that in the first line. .content { line-height: 35px; } <div class="content" contenteditable="true"> ...

Conditional validation in Typescript based on the nullability of a field

I have come across the following code snippet: type DomainFieldDefinition<T> = { required?: boolean } type DomainDefinition<F, M> = { fields?: { [K in keyof F]: DomainFieldDefinition<F[K]> }, methods?: { [K in keyof M]: M[K] & ...

Is there a way to create a universal script that works for all modal windows?

I have a dozen images on the page, each opening a modal when clicked. Currently, I've created a separate script for each modal. How can I consolidate these scripts into one for all modals? <!-- 1 Modal--> <div class="gallery_product col-lg-3 ...

Axios Instance class request cancellation

In my Redux-saga project, I am working on implementing a polling function where I need to make a request every second. If there is no response from the endpoint, I want to cancel the previous request and initiate a new one using Axios client. I have organi ...