Trying to create a function in TypeScript that works like lodash's "bindKey"?

I am looking to create a function that serves as a shortcut for obj.func.bind(obj). It should work like this:

const bound = <...>(obj: ..., fnKey: ...) : ... => obj[fnKey].bind(obj);

const obj = {
  a: "abc",
  b() {
    console.log(this.a);
  }
}

const f = bound(obj, "b"); //it would be great if intellisense displayed all keys with a function value as the second argument
f(); //typed correctly

I have tried various options, one of them being:

function bound<
    K extends string,
    F extends (...args: any[]) => any,
    T extends {[key in K]: F}
>(thisObj: T, fnKey: K): (...args: Parameters<F>) => ReturnType<F> {
    const fn : F = thisObj[fnKey];
    return fn.bind(thisObj);
}

However, none of them seem to yield the expected result, as the return value is typed incorrectly:

const obj = {
    a: "abc",
    foo() {
        console.log(this.a);
    },
};

const f = bound(obj, "foo"); //(...args: any[]) => any

Additionally, when I try to avoid 'any' and specify

F extends (...args: never[]) => unknown
, I receive a TypeScript error
Type 'unknown' is not assignable to type 'ReturnType<F>'
.

The @types/lodash definition seems to have left this function essentially untyped.

Answer №1

In my opinion, a simple general solution will work here. I have introduced an additional condition to ensure that a keyof T is genuinely callable.

const bound = <T extends Record<any, any>, F extends keyof T>(
  obj: T,
  fnKey: T[F] extends (...args: any[]) => any ? F : never
): T[F] => obj[fnKey].bind(obj);

const obj = {
  a: "abc",
  b() {
    console.log(this.a);
  }
};

const f = bound(obj, "b");
f(); // "abc"

TypeScript 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

Exploring ways to establish communication between parent and child components through click events

I am currently working on an Angular 8 application that involves a parent-child relationship. The parent component, DossierCorrespondenceComponent, contains a function that needs to be triggered from within the child component. This is the function in th ...

When using the ionic 3 storage.get function, it may return a null value when accessed outside

In regards to storage, the function is returning a null value outside of the function. Below is the code snippet: username:any; this.storage.get('user').then((value) => { this.username = value; }); console.log(this.username); Ou ...

What methods exist for creating visual representations of data from a table without relying on plotting libraries?

Is there a way to plot graphs directly from a Data Table without the need for external graph libraries like plotly or highcharts? Ideally, I am looking for a solution similar to ag-grid where the functionality comes built-in without requiring manual code ...

TypeError thrown by Mapbox markers

Looking to incorporate markers into my map using Mapbox. Below is the Angular TypeScript code I am working with: export class MappViewComponent implements OnInit { map: mapboxgl.Map; lat = 41.1293; lng = -8.4464; style = "mapbox://styles/mapb ...

Pause code execution and prompt user interaction within a loop - React

I have been working on adding an "add all" button to my React app. To achieve this, I am passing a function to the onClick method of the button: for (element in elements) { await uploadfunction(element) } const uploadfunction = async (element) => ...

I encountered an issue with Cypress when attempting to utilize a custom command. The error message "TypeError cy.login is not a function" keeps popping up. Any suggestions on how to resolve this

I am currently working on a TypeScript project and I am attempting to write some tests using Cypress. However, I encountered the following error: TypeError - cy.login is not a function. This error occurred during a before each hook, so we are skipping the ...

Guide on implementing Regular Expressions in Directives for validation in Angular 8

Managing 8 different angular applications poses its unique challenges. In one of the applications, there is a directive specifically designed for validating YouTube and Vimeo URLs using regular expressions. Unfortunately, once the RegExp is declared, ther ...

The issue of transforming a circular structure into JSON arises while using tRPC

While using the t3-stack (Next, tRPC, Prisma, Next-auth, Typescript) tRPC encountered an error on undefined: TRPCError: Converting circular structure to JSON --> starting at object with constructor 'RequestHandler' | property &apos ...

After successfully logging in, the deployed server encounters an Error 503 and shuts down. However, on the development environment, everything runs smoothly as

I am currently in the process of developing an application using NET 6 LTS and Angular 14. Everything runs smoothly on my development environment with IIS express. However, once I deploy the application (release version) on Windows 2019 with IIS 10, I enco ...

Utilize a method categorization while implicitly deducing parameters

Scenario In my project, I have a unique class setup where methods are passed in as a list and can be called through the class with added functionality. These methods are bound to the class (Foo) when called, creating a specific type FooMethod. class Foo { ...

Steps for confirming whether each element in the array includes the specified search string using Typescript and protractor

How can I verify if each element in an array contains a specific search string in Typescript/Protractor? The issue I faced was that the console statements were returning false because they searched for exact matches instead of the search string. Any sugg ...

A TypeScript function that returns a boolean value is executed as a void function

It seems that in the given example, even if a function is defined to return void, a function returning a boolean still passes through the type check. Is this a bug or is there a legitimate reason for this behavior? Are there any workarounds available? type ...

Unraveling the Perfect Jest Stack Trace

Currently, I am in the process of debugging some tests that were written with jest using typescript and it's causing quite a headache. Whenever a test or tested class runs Postgres SQL and encounters an error in the query, the stack trace provided is ...

To work with Typescript, the 'unknown' type needs to be equipped with

I encountered an issue in vscode stating "Type 'unknown' must have a 'Symbol.iterator' method that returns an iterator." for the following line of code: bookmarks.push(...this.$auth.user?.bookmarks); let bookmarks = []; if(this.$au ...

Utilizing an if statement with a TypeScript DeepMap Union Type

I am attempting to create a Union type that includes optional fields in its structure. Here are the types I have defined: export type StartEndType = { start_date: string; end_date: string; }; export type PayrollContract = StartEndType & { type: ...

Achieving seamless integration among react-templates, TypeScript, and webpack

I am attempting to integrate TypeScript, react-templates, and webpack for a seamless workflow. My starting point was the sample code provided at https://www.typescriptlang.org/docs/handbook/react-&-webpack.html. The configuration in the webpack.config ...

Utilizing a Function's Parameter Type in TypeScript: A Beginner's Guide

Currently, I am creating a custom method that wraps around Angular's HttpClient service. I want users to have the ability to pass in options, but I am struggling to find the proper way to reference that type in my method parameter definition. For exa ...

Retrieve an array of object values using Angular and TypeScript

I'm attempting to extract the values of objects in an array using a nested for loop. I am receiving JSON data as shown below and have written the following TypeScript code to achieve this. However, I am unable to successfully bind the values to the te ...

Invoke cloud functions independently of waiting for a response

Attempting a clever workaround with cloud functions, but struggling to pinpoint the problem. Currently utilizing now.sh for hosting serverless functions and aiming to invoke one function from another. Let's assume there are two functions defined, fet ...

The functionality of Angular 6 Material Nested Tree is disrupted when attempting to use dynamic data

In Angular 6, I am utilizing mat-tree along with mat-nested-tree-node. My objective is to dynamically load the data when the user toggles the expand icon. Attempting to apply the dynamic data concept from the Flat Tree example provided in Material Example ...