Iterative Type inspired by Lodash

As I develop a method to iterate over an array of objects, my goal is to incorporate the use of an iteratee in a similar manner as lodash. The iteratee should be able to act as either a key within the object or a function that accepts the object and returns a value. Furthermore, I aim to enforce constraints on the type of the resulting value.

Initially, I require the functionality to retrieve all keys of a specific type that match a particular value type.

type KeysMatchingValueType<T, V> = {
  [K in keyof T]-?: T[K] extends V ? K : never;
}[keyof T];

Subsequently, I define the Iteratee type.

type Iteratee<T, V> = KeysMatchingValueType<T, V> | ((item: T) => V);

Lastly, there exists a function that takes an object of type T along with an Iteratee, returning a value.

function getNumericValueFromIteratee<T>(
  item: T,
  iteratee: Iteratee<T, number>
): number {
  return typeof iteratee === 'function' ? iteratee(item) : item[iteratee];
}

Nevertheless, TypeScript generates an error:

Type 'number | T[KeysMatchingValueType<T, number>]' is not assignable to type 'number'.
   Type 'T[KeysMatchingValueType<T, number>]' is not assignable to type 'number'.
     Type 'T[T[keyof T] extends number ? keyof T : never]' is not assignable to type 'number'.
         Type 'T[keyof T]' is not assignable to type 'number'.
            Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'number'.
               Type 'T[string]' is not assignable to type 'number'.

Answer №1

function extractNumericValueFromKey<
  T extends Record<K, number>,
  K extends keyof { [K in keyof T as T[K] extends number ? K : never]: 1 },
>(
  item: T,
  key: K | ((t: T) => number)
): number {
  return typeof key === 'function' ? key(item) : item[key];
}

extractNumericValueFromKey({ a: 1, b: 'foo' }, 'b')
extractNumericValueFromKey({ a: 1, b: 'foo' }, 'b') //err
extractNumericValueFromKey({ a: 1, b: 'foo' }, 'c') //err

This function operates smoothly because:

  • T[K] is always a number due to the constraint
    T extends Record<K, number>
  • The constraint
    T extends Record<K, number>
    does not necessarily require Record<string, number>
  • K extends string would also work effectively, although autocompletion wouldn't be available

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

How to effectively sort through users in Angular 6 without the need for a custom pipe

I am looking to customize the user.component template by implementing a filter functionality that will display only the users in the array that match the string entered in the text input field. Is there a way to bind the input value to the view without rel ...

Pushing an object into an array that is a state object in React using Typescript, the proper way

I am working on maintaining an array of objects stored in a state object. Each time the Add button is clicked, I need to push a new object to this array and store it. However, I am facing issues with fetching proper values when trying to submit. Where cou ...

PhpStorm 2019.2 introduces Material UI components that have optional props instead of being mandatory

My PhpStorm 2019.2 keeps showing me a notification that the Button component from Material UI needs to have an added href prop because it is required. However, when I refer to the Material UI API, I see something different. Take a look at this screenshot: ...

When conducting a test, it was found that the JSX element labeled as 'AddIcon' does not possess any construct or call signatures

Here is a code snippet I'm currently working with: const tableIcons: Icons = { Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />), Check: forwardRef((props, ref) => <Check {...props} ref={ref} />) }; const AddIcon ...

Issues with ion-slides functionality in Ionic 3 not functioning properly on web browsers

When using ion-slides in Ionic 3, everything functions correctly on Android and iOS apps; I am able to swipe each row individually while the others remain stationary. However, when attempting to "swipe" using the mouse on a browser, the expected behavior ...

Incorporating debounce functionality in React text input using lodash throttle and Typescript

I've been having trouble getting this text input throttle to function properly in my React project, despite spending a considerable amount of time reading documentation. import { throttle } from 'lodash'; ... <input type="t ...

"Using Typescript, we can switch the keys and values in a JSON object to their corresponding values and

I have been attempting to switch keys with values and vice versa, but I haven't been able to find the correct solution using JavaScript/TypeScript. course = [ { "name" : "John", "course" : ["Java ...

Modified Expression Problem

Scenario : On the left side of the screen, all unpaid bills are displayed. When a user clicks on a bill, its details appear on the right side. Upon clicking the pay button, the bill is marked as paid and should no longer be visible on the left side. This ...

When testing my POST request online, it functions properly. However, I am facing difficulties in getting it to work in next.js as I keep receiving a 405

I am currently working on establishing a connection to Zoho Creator in order to retrieve some data. After successfully testing the request on and receiving the correct response, I encountered an issue while trying to implement it within a next.js applicat ...

The class constructor in the TSdx package must be invoked with the 'new' keyword

I recently developed a npm package using TSdx to create a small Jest reporter. However, when I try to use this package in another project, an error occurs. Uncaught TypeError: Class constructor BaseReporter cannot be invoked without 'new' at ...

What is the process for manually testing a TypeScript function within a React application?

Hey there, I have a question as a beginner. I am currently using React and TypeScript with create-react-app, and I have some JavaScript code that is not related to the user interface (it's a module for working with a REST API). Here is an example of w ...

Please indicate the data type in Vue using Typescript

I'm currently struggling with Vue (3) + Typescript while attempting to specify a data property with a specific type. I have created a .d.ts file, but unfortunately, it hasn't helped. This is what I'm trying: import Modeler from 'bpmn-js ...

Relocating to new pages as WebSocket connection terminates and then reconnects

Currently working on a React project with Vite, encountering an issue where the websocket connection closes and re-establishes when navigating to another page using the sidebar. Main.tsx :- import ReactDOM from 'react-dom/client'; import App fro ...

What is the best way to retrieve entire (selected) objects from a multiselect feature in Angular?

I'm facing an issue with extracting entire objects from a multiselect dropdown that I have included in my angular template. Although I am able to successfully retrieve IDs, I am struggling to fetch the complete object. Instead, in the console, it dis ...

Binding an ID to an <ion-textarea> in Ionic 3

Can an ID be assigned to an ion-textarea? For example: <ion-textarea placeholder="Enter your thoughts" id="thoughtsBox"></ion-textarea> Thank you very much ...

Clicking on a button to transfer items between pages (Ionic 2 + Angular 2)

I'm in the process of creating a recipe application and one feature I'd like to include is a shopping list page. On this page, users can click an "Add to Shopping List" button which will transfer the ingredients listed in a <ul> onto anothe ...

In TypeScript, what is the return Type of sequelize.define()?

After hearing great things about TypeScript and its benefits of static typing, I decided to give it a try. I wanted to test it out by creating a simple web API with sequelize, but I'm struggling to understand the types returned from sequelize. Here ar ...

The modification in Typescript's type order from version 1.7 to 1.8 resulted in a significant

A Visual Studio Cordova application with a unique TypeScript source structure: /src /app /appsub1 appsub1.ts -> 4 : 7 /appsub2 appsub2.ts -> 5 : 6 app.ts -> 3 : 5 /mod1 /mod1sub1 mod1sub1.ts -> 7 : 4 m ...

Asynchronous retrieval of reference value from Firebase Firestore in ReactJS

Encountering a peculiar bug in TypeScript-JavaScript where I have a Model class in TypeScript and a ReactJS Component in JS. The issue arises when dealing with a list of Promo Objects, each containing a "_listCompte" property which holds a list of Compte O ...

Modify the height of React Cards without implementing collapse functionality

Currently, I am in the process of developing a web interface that displays various processes and services. The information is presented in React cards that support expand/collapse functionality. However, I am facing an issue where expanding one card affect ...