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

I'm looking for a way to merge the functionalities of tsc build watch and nodemon into a single Node.js

Currently, I have two scripts in my code: "scripts": { "build": "tsc -p . -w", "watchjs": "nodemon dist/index.js" } I need to run these two scripts simultaneously with one command so that the build ...

What are the steps for publishing a Three.js project on github pages?

Currently, I've been putting together my own personal portfolio website which involves using the Three.js library. The library has been downloaded onto my laptop and when running locally, everything works smoothly. Now, I want to move forward by deplo ...

Exploring the implementation of constructors and classes in JavaScript

I have a task to create a class named ShoppingCart with specific instructions: The class should have a constructor that initializes the total attribute to zero and creates an empty dictionary attribute called items. There should be a method named add_ite ...

The blur() function does not function properly on IOS devices such as iPad and iPhone

I've attempted using blur() to change the CSS, but it seems that this function is not effective. After researching, I discovered that blur() does not work on IOS devices. Is there an alternative method for removing the position from .body-clip-overflo ...

Incorporate fresh data into dropdown options upon selection using Vue3

Can anyone assist me with populating specific input fields on a form using Vue 3? Currently, when a user selects an option from my dropdown menu, all inputs are displayed instead of just the relevant ones. Below is the select dropdown code: <select v- ...

Which behaviors that are typically exhibited by browsers will be stopped by calling `event.preventDefault()`?

While I grasp that using event.preventDefault() stops default actions triggered by events in the browser, I find this explanation too general. For instance, what exactly are these default event behaviors in the browser? It's common to see developers u ...

How to change a specific value in an array of objects using React

Within my array, I have objects containing the fields id and title const cols = [ { id: 0, title: "TODO" }, { id: 1, title: "InProgress" }, { id: 2, title: "Testing" }, { ...

Tips for extracting title and image from someone else's blog posts to share on your own website

Currently, I am in the process of creating a website where I can showcase my personally curated content. I have been struggling to figure out how to seamlessly integrate this content into my site without relying on an API. My initial idea was to manually ...

Validating a model in Mongoose: Best practices for updating data

I am facing an issue with my model. It seems that while creating, incorrect information is prohibited, but when editing, it is allowed. How can I prevent this from happening? var userSchema = new Schema({ cartaoCidadao: { type: String, require ...

Utilizing TypeScript in Kendo UI for JQuery

I have implemented KendoUI for JQuery using TypeScript. Here is an excerpt from my "package.json" file: "dependencies": { "@progress/kendo-theme-material": "^3.19.2", "@progress/kendo-ui": "^2020.3.915 ...

What is the best way to make IE 10 display a pointer instead of an I-bar for a select list?

Is there a way to make IE 10 display a pointer instead of an I-bar when selecting from a list? Despite trying various methods found in similar questions, I have been unable to resolve this issue. The cursor: pointer property works as expected on other br ...

Rendering HTML or links sourced from encoded JSON data with JavaScript

After making an ajax call, I receive the following data: {"dataList":[{"date":"August 27, 2013","text":"<a href=\"http:\/\/www.example.com\/test.aif\" title=\"Click here to listen\" target=\"\">Click her ...

Vue error: Uncaught promise rejection - RangeError: The computed value update has exceeded the maximum call stack size

My computed code snippet: computed: { display: { get() { return this.display }, set(newValue) { this.display = newValue } } }, Attempting to update the computed value from a function in ...

Obtaining a return value from a function that involves a series of chained Ajax requests in jQuery

I'm facing an issue with my function that involves chained Ajax requests. Function A and B are both Ajax requests, where A runs first and B runs after A returns its data. The problem arises when Function C executes Function B. Upon execution of Funct ...

Encountered an issue while executing the next build process

Every time I run npm next build, it throws an error message. Despite my efforts to search for a solution online and installing the "extract-text-webpack-plugin," the issue persists. The error being thrown is as follows: > next build (node:8136) Depre ...

Is there a way to utilize the child component's method?

I am looking to access a child component's method from the parent in Vue.js. To achieve this, I plan on using $refs. Code Example: <template> <div>Parent!</div> </template> Script: <script> Vue.component('c ...

Using Vue.js and axios to manipulate injected HTML content

I am currently working on a project using vue.js and axios to fetch the latest post content from a specific category of a WordPress site using REST API. The post content is always in the form of an ordered list (OL) which will then be displayed as a carous ...

Tips for displaying the HTML content within the autocomplete box

My situation involves a text input and an HTML form where users can submit their name to retrieve information. I am using AJAX to display the usernames dynamically. <div class="hidesearch" id="search" style="width:"400px;"> <inp ...

"Using the selected option from a dropdown list to pass to a PHP file for autocomplete functionality

Although there is no error in the code, I am facing an issue where, after selecting an option from the brands dropdown, when I type in the product field, it passes "%" instead of the brand id (1, 2, or 3). Is there a way to modify the code so that it passe ...

Bar chart in Highcharts vanishing following the update from version 10.2.1 to 10.3.1

I've been in the process of updating my highcharts to the latest version, but I've hit a roadblock. Specifically, I have a bar chart set up with the following configuration: { chart: { type: 'bar', ...