Pass the type of the "keyof" variable as a parameter

Imagine having the interface below:

interface ITest {
 a: number;
 b: string;

Now, I am looking to create a function with similar functionality:

public filterByPropertyValue<T>(array: T[], key: keyof T, value: typeof ????) {
  return array.filter(e => e[key] === value)
}

Specifically, the examples provided should not work:

const array: ITest[] = [ {a: 1, b: 'some'}, {a: 2, b: 'value'}];

filterByPropertyValue<ITest>(array, 'a', 'abc') // because 'a' is of type number
filterByPropertyValue<ITest>>(array, 'b', 15) // because 'b' is of type string

However, the following examples should be successful:

const array: ITest[] = [ {a: 1, b: 'some'}, {a: 2, b: 'value'}];

filterByPropertyValue<ITest>(array, 'a', 1) // returns array[0]
filterByPropertyValue<ITest>(array, 'b', 'value') // returns array[1]
filterByPropertyValue<ITest>(array, 'b', 'foobar') // returns an empty array

I experimented with different combinations of typeof and keyof, but I struggled to find a solution when using typeof on a keyof variable.

Answer №1

To make this solution effective, it's essential to include an additional generic type parameter K that corresponds to the type of K. Then, assign the variable value with the indexed access type T[K], indicating "the value type obtained when indexing into an object of type T with a key of type K":

function filterByPropertyValue<T, K extends keyof T>(array: T[], key: K, value: T[K]) {
  return array.filter(e => e[key] === value)
}

This update ensures the desired functionality:

filterByPropertyValue(array, 'a', 15); // successful
filterByPropertyValue(array, 'a', 'abc') // error
filterByPropertyValue(array, 'b', 'abc') // successful
filterByPropertyValue(array, 'b', 15) // error

It is worth noting that the compiler automatically deduced the type arguments without me specifying them manually as in

filterByPropertyValue<ITest, "a">(array, 'a', 15)
. TypeScript does not support partial type argument inference as indicated in ms/TS#26242. Therefore, when invoking this function, you have the choice to either let the compiler infer both type arguments or specify both type arguments manually. Thus, invoking
filterByPropertyValue<ITest>(array, 'a', 15)
using this method is not permissible.

Experience the code on Playground

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

Cannot be assigned to type "never" after applying a type predicate

I'm attempting to merge a method for creating strongly typed strings with type predicates but encountering issues, as evidenced by the following code snippet: https://i.sstatic.net/2b9pO.png The issue I'm facing is TS2339: Property 'substr& ...

Utilize ngx-translate in Ionic 2 for translating menu items

I have successfully implemented ngx-translate for multi-language support in my application. However, I am now looking to extend this functionality to my menu items. How can I achieve this for my 3 menu items with different titles? ts file appPages: Pag ...

Utilizing winston to generate multiple log files with set maximum sizes and daily rotation

Currently, I am utilizing winston for logging with a maximum size and daily rotation. I am interested in having this functionality with one file per API endpoint to define multiple log files. Is there a way to achieve this? Displayed below is my winston ...

Can you explain the significance of the angle brackets "<>" in a Typescript function declaration?

When working with TypeScript code, I often come across code enclosed in angle brackets, similar to HTML. Despite knowing that they are not HTML elements, and understanding that the content within the angle brackets represents types, I frequently encounter ...

Has anyone made the switch from using exports and require in Typescript to consolidating everything into a single file output?

When we first started our TypeScript project, we used external modules with "require Foo = ('./Foo')" which proved to be very organized and useful. However, it required us to use requirejs (AMD modules) or a similar method. While this wasn't ...

Provide a parameter for a function's callback

I am attempting to utilize lodash's debounce function to delay the onChange event. See the code snippet below. import React, { useState, useEffect, useCallback } from "react"; import { TopBar } from "@shopify/polaris"; import { debounce } from "lodas ...

How can we leverage the nullish coalescing operator (`??`) when destructuring object properties?

When working with ReactJS, I often find myself using a common pattern of destructuring props: export default function Example({ ExampleProps }) { const { content, title, date, featuredImage, author, tags, } = ExampleProps || {}; ...

Typescript defines types for parameters used in callbacks for an event bus

Encountering a TypeScript error with our custom event bus: TS2345: Argument of type 'unknown' is not assignable to parameter of type 'AccountInfo | undefined'. Type 'unknown The event bus utilizes unknown[] as an argument for ca ...

Utilizing a fixed array as the data source for a mat-table

I am currently working on implementing the Angular Material table into my project. I am encountering an issue when trying to define the [dataSource]="data", even though I am using code similar to the examples provided. My question may seem basic, but my t ...

Can PassportLocalDocument and PaginateModel coexist within the same framework?

I am new to TypeScript and NestJS, looking to implement a pagination feature for all models in my application. Currently using NestJS with Mongoose for the API project. Here is an example of the user schema: export const UserSchema = new mongoose.Schema( ...

Exploring Angular 2/4: Unpacking the Process of Accessing API Data Using Tokens

Hello there, I am trying to retrieve API data with a token using Angular 2/4. Below is the code I have written: import { Component, ViewEncapsulation } from '@angular/core'; import { Http, Response } from '@angular/http'; import &apos ...

I attempted to implement a CSS and Typescript animation for a sliding effect, but unfortunately, it isn't functioning

So I'm encountering an issue with this unique ts code: {/* Mobile Menu */} <div className="lg:hidden"> <button className="flex items-center w-8" onClick={toggleMenu}> {isMobileMenuOpen ? ( ...

The property 'item' is not found within the specified type 'IntrinsicAttributes & RefAttributes<Component<{}, any, any>>'. Error code: 2322

"react": "^16.12.0", "typescript": "^4.0.3", "next": "^9.4.4" The error being raised by typescript is related to the <Item item={item} key={item.id} urlReferer={urlReferer} /> prop used ...

Tips for encapsulating a promise while maintaining the original return type

In my code, there is a function that utilizes an axios instance and is of type async function register(data: RegisterData): Promise<AxiosResponse<UserResponse, any>> export const register = (data: RegisterData) => api.post<UserResponse> ...

Tips for migrating an AngularJS application to Angular

My current project involves implementing a basic search function using AngularJS (link). I want to integrate this feature into an existing Angular application. To do this, I created a new Angular app and transferred the view to app.component.html. <hea ...

Encountered an unexpected token error while using Jest with TypeScript, expecting a semicolon instead

I have been struggling to configure jest for use with typescript and despite trying several solutions, I am still facing issues. The error SyntaxError: Unexpected token, expected ";" keeps popping up, indicating that the configuration may not be compatible ...

Ways to display all current users on a single page within an application

I have come across a project requirement where I need to display the number of active users on each page. I am considering various approaches but unsure of the best practice in these scenarios. Here are a few options I am considering: 1. Using SignalR 2. ...

Error in VS code with React: The specified property 'button' is not recognized in type 'JSX.IntrinsicElements'

As I embarked on creating my debut React application using vs code, I encountered a perplexing issue. The software kept highlighting all the HTML within the .tsx files and presenting me with the following error message: Property 'button' does not ...

There are no properties shared between type 'dateStyle: string' and type 'DateTimeFormatOptions'

"typescript": "^4.0.3" Can anyone help me resolve the TypeScript error I am encountering in the code below?: components/OrderListItem.tsx const newedate = (_date) => { const options = {dateStyle: 'medium'}; //{ weekday: ...

Oops! Property 'month' cannot be set on undefined value due to a TypeError

Despite not receiving any errors from Visual Studio Code, I’m encountering an error in Chrome's console. Below is the code snippet from my interfaces.ts file: export interface Data1{ month: string; employeeName: string; date: string; employmentSta ...