Guide to setting a generic key restriction on a function parameter

Today, I decided to have some coding fun and try creating a generic pushUnique function. This function is designed to check if a new object being added to an array is unique based on a key, and then push it if it meets the criteria.

At this point, all I have is pseudo-code that clearly won't work:

  pushUnique<T, U>(arr: T[], obj: T, key: U = null) {
    if (key !== null) {
      const index = arr.findIndex(o => o.key === obj.key);
    }
  }

I'm struggling with figuring out how to get the object name of the key and specify it for the findIndex function. Any ideas?


UPDATE:

Thanks to Titian Cernicova-Dragomir's help, here is my improved solution that serves my proof-of-concept needs perfectly!

export class Utils {
  pushUnique<T, U>(arr: T[], obj: T, key: (o: T) => U = null, logVerbose: boolean = false): void {
    if (logVerbose === true) {
      console.log('pushUnique called');
    }

    if (typeof obj === 'object' && key === null) {
      console.warn('Object defined in pushUnique is complex, but a key was not specified.');
    } else if (typeof obj !== 'object' && key !== null) {
      console.warn('Object is not complex, but a key was specified');
    }

    const index = key !== null ? arr.findIndex(o => key(o) === key(obj)) : arr.indexOf(obj);
    if (index === -1) {
      arr.push(obj);
    } else {
      if (logVerbose === true) {
        console.log('Duplicate object, not added');
      }
    }
  }
}

Answer №1

To access the key typed as keyof T, it must be a key of whatever object is passed in as T. Then, index access can be used to retrieve the value:

class Helper {
    extractUnique<T>(arr: T[], obj: T, key: keyof T) {
        if (key !== null) {
            const index = arr.findIndex(o => o[key] === obj[key]);
        }
    }
}

new Helper().extractUnique([{a: 1}], {a :2 }, "a")
new Helper().extractUnique([{a: 1}], {a :2 }, "b") //error

An alternative approach is using a function instead of keyof, which is how things are typically done in JavaScript/TypeScript:

class Helper {
    extractUnique<T, U>(arr: T[], obj: T, key: (o: T) => U) {
        if (key !== null) {
            const index = arr.findIndex(o => key(o) === key(o));
        }
    }
}

new Helper().extractUnique([{a: 1}], {a :2 }, o => o.a)
new Helper().extractUnique([{a: 1}], {a :2 }, o => o.b) //error

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

Is there a built-in method or library for extracting data from JSON strings in programming languages?

Duplicate Query: how to parse json in javascript The data sent back by my server is in JSON format, but it doesn't follow the usual key/value pairs structure. Here's an example of the data I'm receiving: ["Value1","Value2","Value3"] ...

Assigning an argument of type `any` to a parameter of type `Observable<IComboboxItem[]>` can be considered risky

I have a piece of code that retrieves data from the backend server. Here is the code snippet: @Injectable() export class DictionariesDatasourceFacadeService { public invoiceTemplate: IDataSource<IComboboxItem>; public replacedLegalEntity: IData ...

Guide on redirecting to a new domain using a cookie in Express.js

I am working on a web app using Express on Node and I want to add a proxy login feature that allows users to be automatically logged in and redirected to another site after logging into my site. Within my routing function, I have the following code: res ...

Showing text on an ajax loader

While making an ajax call, I have implemented functions that are called on success. To enhance user experience, I am displaying a spinner during the call and hiding it once completed. My goal is to show a message along with the spinner to indicate which fu ...

IntersectionObserver activates prior to element's entrance into the viewport

I've set up a Vue component with the following structure: <template> <article> <!-- This content spans several viewport heights: you *have* to scroll to get to the bottom --> {{ content }} </article> <span ref ...

Set the display property of all child elements within the DIV to none

CSS <div class="container"> <span></span> <input type="text"> </div> JavaScript function hideElements(){ let container = document.querySelector(".container"); let elements = ...

Establish a connection between the MySql database in WHM (phpmyadmin) and a node.js application

Our team has been working on setting up the database connection with Mysql using node.js in Cpanel. Although I didn't create the database myself, I have all the necessary information such as the host, user, password, name of the database, and port nu ...

Using AJAX (jQuery) to process and refine JSON data through filtration

I need assistance with filtering a JSON array using AJAX but I'm unsure of how to proceed. { posts: [{ "image": "images/bbtv.jpg", "group": "a" }, { "image": "images/grow.jpg", "group": "b" }, { "image": "images/tabs.jpg", ...

Uploading Files with Vuetify 2 v-file-input and AxiosIn this tutorial, we

After researching extensively on the topic, I reviewed questions such as file-upload-in-vuetify and vuetify-file-uploads, but unfortunately, the solutions provided did not work for me. My current challenge involves utilizing Vuetify 2's <v-file-in ...

Is it possible to simultaneously utilize a Node.js server and an ASP.NET web service?

Although I have experience in developing with .NET, I am new to Node.js and intrigued by its advantages. I believe it is a great way to maintain code and promote reusability. However, I am faced with a dilemma. I understand that Node.js allows for creatin ...

What are effective strategies for safeguarding my AngularJS application code, particularly from unauthorized access through the browser's source code?

I am currently working on an AngularJS application. I have encountered a challenge where the end user is able to view the app code from the browser's source code. I am seeking advice on how to address this issue effectively. Is there any recommended ...

What is the correct way to securely send the username and password from a ReactJS frontend to the backend for authentication?

My React application includes an onChange function on a form that collects username and password. Upon submission, the username and password are sent to the server side using redux dispatch in Node.js. On the server side, I am authenticating the credentia ...

In my attempt to simulate redis using jest and javascript, I've noticed that whenever I try to access redis.mock.instance[0], it consistently returns as empty

I'm currently attempting to simulate redis with jest and JavaScript, but I'm encountering an issue where accessing redis.mock.instance[0] always returns empty. RedisWrapper.js: const Redis = require('ioredis'); const REDIS_USER_TTL = 6 ...

The code is functioning properly in the output, but it does not seem to be

I have been utilizing jquery chosen to implement a specific functionality, which is successfully demonstrated in the image below within the snippet. However, upon uploading the same code to my blog on Blogger, the functionality is not working as expected. ...

What is the proper way to send an AJAX request with the data type set to

I am currently working on creating my own POST request. Below is the function I have written: function sendPost(o) { var h = new XMLHttpRequest(); h.onreadystatechange = requestComplete; function requestComplete() { if (h.readyState = ...

The parameter in the Typescript function is not compatible with the generic type

What causes func1 to behave as expected while func2 results in an error? type AnyObj = Record<string, any>; type Data = { a: number; b: string }; type DataFunction = (arg: AnyObj) => any; const func1: DataFunction = () => {}; const arg1: Data ...

Issue encountered with Ionic and ssh2: process.binding is not supported

I am currently delving into the world of Ionic and experimenting with creating a basic application that utilizes SSH2 to establish an ssh connection between the app and a server. Here is a breakdown of the steps I took to encounter the issue: Steps to Rep ...

How to extract IDs from a URL in Angular

I'm facing an issue with retrieving the first id from an image URL. Instead of getting the desired id, I am receiving the one after the semicolon ("id" = 1). I have tried various methods but haven't been successful in resolving this issue. Any su ...

Dynamically assigning anchor tags to call JavaScript functions

Creating a list dynamically, full of <span class="infa9span"><img src="/csm/view/include/images/foldericon.png"/><a id="infa9Service">'+servicename+'</a><br/></span> tags. This list is then appended to a div. ...

Issue: Unable to extract the 'title' property from '(0 , react__WEBPACK_IMPORTED_MODULE_1__.useContext)(...)' as it is not defined (Next.js Chat App)

Currently facing an issue with the error message "Cannot destructure property 'title' of '(0 , react__WEBPACK_IMPORTED_MODULE_1__.useContext)(...)' as it is undefined" while developing a chat application using Next.js and Solidity. Desp ...