Developing Sets and Arrays in TypeScript from a list of numbers or strings

I am currently working on a function that takes an array of numbers or strings and returns a Set containing unique elements:

 const f = (arr: number[] | string[]): number[] | string[] => {
    return [...new Set(arr)]; 
}

However, I am encountering an error message:

The call does not match any overload.
Overload 1 of 2, '(iterable?: Iterable | null | undefined): Set', produced the following error. The argument 'number[] | string[]' cannot be assigned to a parameter of type 'Iterable | null | undefined'. Type 'string[]' cannot be assigned to type 'Iterable'. The types returned by 'Symbol.iterator.next(...)' are incompatible between these types. Type 'IteratorResult<string, any>' cannot be assigned to type 'IteratorResult<number, any>'. Type 'IteratorYieldResult' cannot be assigned to type 'IteratorResult<number, any>'. Type 'IteratorYieldResult' cannot be assigned to type 'IteratorYieldResult'. Type 'string' cannot be assigned to type 'number'.
Overload 2 of 2, '(values?: readonly number[] | null | undefined): Set', produced the following error. The argument 'number[] | string[]' cannot be assigned to a parameter of type 'readonly number[] | null | undefined'. Type 'string[]' cannot be assigned to type 'readonly number[]'. Type 'string' cannot be assigned to type 'number'.

I can change the input type from number[] | string[] to (number | string)[], but this means that the array could contain both numbers and strings simultaneously, which is not what I intend.

const f = (arr: (number | string)[]): (number | string)[] => {
    return [...new Set(arr)];
}

f([1,2,3]);        // okay
f(['1','2','3']);  // okay
f([1,2,'3','4']);  // okay, should actually be error
f([true, {}, 1]);  // should be an error, as expected

Answer №1

UPDATE: After some investigation, it appears that this is related to TypeScript configuration. One way to handle this is by spreading the array you are creating the set from and then casting the return value, like this:

const f = (arr: number[] | string[]): number[] | string[] => {
    return Array.from(new Set([...arr])) as number[] | string[];
}

As mentioned by udalmik, you can use any, but that somewhat defeats the purpose.

Answer №2

To eliminate this issue, simply cast the argument to any[]:

function process(data: number[] | string[]): number[] | string[] {
    return [...new Set(data as any[])];
}

Answer №3

I believe either of these options could be more effective

const func = <T extends number[] | string[]>(array: T):  T => {
    return <T> [...new Set(array as any[])];
}

let result1 = func([1,2,3,4,5,5,5]);
let result2 = func(['a','b','c','c','c']);
let result3 = func(['a','b','c','a','b',1,2,3,4]);//error
function func(arr:number[]):number[];
function func(arr:string[]):string[];
function func(arr:any[]):any[]{
    return [...new Set(arr)];
}

let result1 = func([1,2,3,4,5,5,5]);
let result2 = func(['a','b','c','c','c']);
let result3 = func(['a','b','c','a','b',1,2,3,4]);//error

In this manner, the function strictly accepts arrays of numbers or strings but not a mix of both, maintaining the return type integrity. If an array of numbers is passed in, Typescript correctly identifies the return value as an array of numbers.

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

The concept of Nested TypeScript Map Value Type

Similar to Nested Typescript Map Type, this case involves nesting on the "value" side. Typescript Playground const mapObjectObject: Map<string, string | Map<string, string>> = new Map(Object.entries({ "a": "b", &quo ...

Why do array[0] and array.first behave differently in Swift?

Within my LazyVGrid, I have a ScrollView. Inside, there is a forEach loop that creates views as they appear. Users are able to create new items in this ScrollView. When a new view is created, I observe changes in a custom Bool property that toggles and scr ...

Creating a clickable button that will trigger a function when pressed, continuously running the function until the button is released

I am currently working on a project where I am trying to make an object move using an HTML button. However, the function is only executed once with a single click, whereas I want it to execute continuously as long as the button is pressed down. Below is ...

Uncertain about the ins and outs of AJAX

I am a complete beginner in web development. Although I have studied JavaScript and HTML through books, my understanding is still limited. I have never worked with AJAX before and find most online examples too complex for me to follow. My goal is to crea ...

SlickGrid checkbox formatter/editor experiencing issues with data consistency

Exploring the functionalities of SlickGrid'seditors/formatters, I delved into how these features could potentially alter the data object utilized for constructing the grid (as modifications within the table are usually reflected in the original data o ...

Obtaining input value when button is clicked

I am currently working on a feature where, upon clicking the Submit button, I aim to retrieve the value entered into the input field in order to update the h1 element. import React from "react"; function App() { const [headingText, setHeadingT ...

Customize Your Calendar: A Guide to Disabling Dates with Pikaday.js

Wondering how to disable specific days on a calendar? Look no further! Here's a solution using the `disableDayFn` option from Github: disableDayFn: callback function that gets passed a Date object for each day in view. Should return true to disable s ...

Simple ways to simulate Axios requests in tests

My implementation includes the use of axios with a custom HttpClient class export default class HttpClient { constructor(baseUrl: string) { const axiosInstance = axios.create({ validateStatus(status: number) { return status === 200 || s ...

Using Angular 4's ngModel can result in the transformation of data type from 'number' to 'string'

I am facing an issue with my Angular4 app where data captured from a form is stored in DynamoDB. The problem arises when an input field typed as 'text' is bound to a Typescript 'number' field, which seems to be converting the object val ...

Hold on until the page is reloaded: React

My current setup includes a React Component that contains a button. When this button is clicked, a sidePane is opened. What I want to achieve is refreshing the page first, waiting until it's completely refreshed, and then opening the sidepane. Below i ...

Is the transition not smooth when sliding the element up and down on mobile devices?

I have successfully implemented a modal that slides up and down when clicked using CSS and jQuery. While it looks decent on desktop, the animation is choppy on mobile devices, especially when the modal slides down. I have searched for solutions to achiev ...

Issue encountered while serializing data in next.js when utilizing getServerSideProps function

Encountering An Error Error: The error message "Error serializing .myBlogs returned from getServerSideProps in "/blog"" keeps popping up. I'm facing a problem while attempting to log the data! Initially, when I was fetching data using use ...

The issue with Ionic 2 arises when attempting to use this.nav.push() because it

Recently transitioning from Ionic 1 to Ionic 2, I'm encountering an issue with using this.nav.push(nameOftheOtherPage) immediately after a promise. Interestingly, the function this.nav.push works fine when it's called outside of the promise funct ...

AJAX request bypassed form validation

My form utilizes an AJAX call to submit information to Google Sheets, which works well until I try to incorporate form validation. At that point, only the AJAX call seems to run. Below is the HTML Form: <!DOCTYPE html> <html class="no-js" lang=" ...

When you drag and drop multiple items, the entire data set is erased

I am currently working on a grid that loads data from a JSON file in a React application. When a user holds down the ctrl key on an item, that item is tagged with a new property called selected. My goal is to enable the user to drag and drop the tagged ite ...

Inheritance-based type inference

I have created a class hierarchy to manage inheritance in my code. Here is an example of how it looks: class A { clone(): A { return new A() } methodA() { return this.clone() } } class B extends A { clone(): B{ return new B() } ...

Counting occurrences of characters in a string: A simple guide

I'm working on a function to identify characters from an array within a given string and count how many of them are present. I've attempted to cover every possible pattern, but the task seems overwhelming. I also experimented with the alternativ ...

Make sure to declare rest parameters first when using Typescript

I am dealing with a function that takes in multiple string arguments and one final argument of a complex type, which is called Expression. This particular code looks like this in JavaScript: function layerProp(...args) { const fields = args.slice(0, -1) ...

creating a checkerboard using an array of JPanels

I am currently working on creating a chessboard by using an array of JPanels, where each box represents a JPanel with a specific color. However, I am encountering an issue when I try to make the assignment "chessboard[rows][columns] = b" as it results in a ...

The issue with session storage persisting even after closing the iframe

Encountering a persistent issue where the sessionStorage remains populated even after closing an iframe and opening another one with the same destination. I assumed that the sessionStorage would be reset and start afresh each time. The iframe is contained ...