Function in Typescript that accepts either a single object or an array of objects

We frequently use a simple function declaration where the function can accept either a single object or an array of objects of a certain type.

The basic declaration looks like this:

interface ISomeInterface {
    name: string;
}

class SomeClass {
    public names: ISomeInterface[] = [];

    public addNames(names: ISomeInterface | ISomeInterface[]): void {
        names = (!Array.isArray(names)) ? [names] : names;
        this.names = this.names.concat(names);
    }    
}

However, TypeScript throws an "type is not assignable" error in this scenario.

Is there a more efficient way to accomplish this? While we could create two separate functions, I believe handling both single and multiple objects this way is sufficient.

Answer №1

There is a simpler solution available

 combineNames(names: ISomeInterface | ISomeInterface[]): void {
        this.names = this.names.concat(names);
 } 

Source: Mozilla Developer Network

The concat() function creates a new array by combining the original array with additional array(s) or value(s) passed as arguments.

Answer №2

An alternative approach is to utilize the rest parameter:

interface ISomeInterface {
    name: string;
}

class SomeClass {
    public names: ISomeInterface[] = []; // initialize an instance if needed.

    addNames(...names: ISomeInterface[]): void {
        // the names argument will always be passed as an array
        this.names = this.names.concat(names);
    }
}

You can invoke it as follows:

addNames(name1); // passing one name
addNames(name1, name2, name3); // passing multiple names separated by commas
addNames(...[name1, name2, name3]); // passing an array of names

Note that I have omitted the function keyword to prevent any potential scope loss of the this keyword inside the function body.

Answer №3

Here is the solution you are looking for

interface ISomeInterface {
    title: string;
}

class SomeClass {
    public titles: ISomeInterface[];

    addTitles(titles: ISomeInterface | ISomeInterface[]): void {
        titles = (titles instanceof Array) ? titles : [titles];
        this.titles = this.titles.concat(<ISomeInterface[]>titles)
    }    
}

Remember to use instanceOf instead of isArray.

Answer №4

To successfully handle this scenario in typescript, one can utilize multiple function signatures as demonstrated below:

addNames(names: ISomeInterface): void;
addNames(names: ISomeInterface[]): void;
addNames(names: any): void {
    ...
}

For further insights on this topic, refer to the official handbook here

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

Having trouble deciphering the JSON data structure in JavaScript

How can values be passed back to a form that was submitted to the server using Ajax? In this view (shown below), a simple data structure is returned for testing purposes: def detail(request, widget_id): widget = get_object_or_404(Widget, pk=widget_i ...

Executing a Callback in Node with Redis Publish/Subscribe

Is it possible to implement callback with the PubSub design pattern in Node Redis? For example: server.publish("someChanel", someData, function(response) { // Expecting a response from client }); client.on('message', function(channel, data, ...

How can I create a React component that is accessible and controllable from external sources?

Attempting to create a Dialog component using React and Material-UI. Currently, the component behaves like a traditional Material-UI dialog with a button inside the class that opens the dialog. However, I aim to achieve the same behavior as the default Ma ...

Swapping out the default JavaScript random number generator for my custom JSON-based solution

I've been working on creating a D3 graph to display my data. After following a tutorial, I arrived at this particular piece of code: // 8. An array of objects of length N. Each object has key -> value pair, the key being "y" and the value is a r ...

Calculate the total sum of selected values in a multiple select dropdown using jQuery

Is there a way to calculate the sum of selected items in a multiple selection dropdown menu? For instance, if I select "X12SO" and "X13SO", their values should add up to 30. let total = 0; $("select[name='myselect[]'] option").each(function(){ ...

Convert this JavaScript function into a jQuery function

I currently have this JavaScript function: function removeStyle(parent){ var rmStyle = document.getElementById(parent).getElementsByTagName("a"); for (i=0; i<rmStyle.length; i++){ rmStyle[i].className = ""; } } Since I am now using ...

Angular is throwing error TS2322 stating that the type 'string' cannot be assigned to the type '"canvas" while working with ng-particles

My goal is to incorporate particles.js into the home screen component of my project. I have successfully installed "npm install ng-particles" and "npm install tsparticles." However, even after serving and restarting the application, I am unable to resolve ...

Vue.js is failing to re-render the component even after a change is made to

Utilizing Vue.js for my project. I am working with two object arrays, category and categoryPar. The category array contains names and parent names, while the categoryPar array only contains names. My goal is to display only the categories that belong to t ...

Error rendering {message} object on the Chrome Console

In my ReactJS component, I am utilizing the {message} parameter from props. Check out the code snippet below: import React from "react"; const MyMessage = ({ message }) => { if (message?.attachments?.length > 0) { return ( < ...

What steps should I take to incorporate a timer into my bot similar to the timer used by other giveaway bots

I am looking to add a timer to my bot giveaway embed message that continues to update itself even when the bot is offline, without showing that the message was edited. Here's what I currently have in my embed: const embed = new MessageEmbed(); ...

Customize Material UI (MUI) Autocomplete with preset initial selections

My goal is to develop a unique MUI Autocomplete feature that showcases a series of numbers from 1 to 50. Upon user selection, the component should initially only show numbers 1, 6, 10, 12, and 24. If the user inputs '1', it should then display al ...

I encountered an Angular error that is preventing me from updating and uploading images to my Firebase Storage because it is unable to locate the storage bucket

Hey there fellow developers! I'm currently working on a simple Angular app that allows users to upload images to a gallery. However, I've encountered an issue while trying to upload the images to Firebase Storage. I keep getting an error mentioni ...

I'm curious if it's possible to modify a webpage loaded by HtmlUnit prior to the execution of any javascript code

To begin, I want to elaborate on the reasoning behind my question. My current task involves testing a complex web page using Selenium + HtmlUnit, which triggers various JavaScript scripts. This issue is likely a common one. One specific problem I encount ...

How to achieve multiplication in Javascript without utilizing the * operand

Challenge 1 Criteria: This problem involves working with two positive integers N and M. Outcome: Upon completion, the function should output the result of multiplying N and M. For instance, if you input 5 and 8 into the function, it should calculate and ...

Experience the click action that comes equipped with two unique functions: the ability to effortlessly add or remove a class

Currently, I am in the process of creating a list of anchor links that contain nested anchor links, and there are a few functionalities that I am looking to implement. Upon clicking on a link: Add a class of "current" Remove the class of "current" from ...

I attempted to unsubscribe from an observable in Angular, but I encountered an error stating that the unsubscribe function does not exist

Here is the code snippet from a components.ts file in an Angular project. I encountered the following error during compilation: ERROR merge/merge.component.ts:75:12 - error TS2551: Property 'unsubscribe' does not exist on type 'Observable& ...

Looking up a destination with the Google Places API

My dilemma lies in dealing with an array of place names such as 'Hazrat Nizamuddin Railway Station, New Delhi, Delhi, India' and similar variations. These variations serve as alternative names for the same location, adding complexity to my task. ...

Is it necessary to bump the major version if I make updates to a react module that does not affect existing code functionality, but may cause Jest snapshot tests to break?

Imagine I am developing a module for a react component and currently working on a PR to introduce a new feature. Along with this new feature, I have also made changes to the component by refactoring it to eliminate certain internal parts that were previou ...

Presentation: Troubleshooting Ineffective CSS3 Transitions

I have created a basic slideshow that can accommodate multiple images. Clicking on an image should move to the next slide, and once the last image is clicked, it should loop back to the first slide. The functionality of transitioning between slides seems ...

My PHP script is not functioning correctly with Ajax

I am currently working with HTML5, PHP, and JavaScript. My goal is to implement Ajax in order to display the sizes of a selected product when an option is chosen from #productoSeleccionado. However, I believe that there may be an issue with my code as the ...