Determine the data type based on the object property

Can a versatile function be created to automatically determine the type based on an "external" object property?

Consider the following scenario:

const resolversMap: {
  overallRankingPlacement: (issuer: number, args: Record<string, any>, context: Record<string, any>) => Promise<number>;
} = {
  overallRankingPlacement: createResolver((issuer, args, context) => {
    return 0;
  }),
};

function createResolver<T extends () => void>(resolverFn: T): ReturnType<T> {
  return (...args) => {
    // Some additional logic...
    resolverFn(...args);
  };
}

The objective is for the function generated by createResolver to perfectly match the return of "overallRankingPlacement", with arguments mirroring and proxying the same—ensuring consistent types throughout.

Answer №1

To achieve this functionality, you can utilize generic parameters for both the argument-array and the result type. By implementing something similar to the code snippet below:

function createResolver<Args extends unknown[], Res>(
  resolverFn: (...args: Args) => Res
): (...args: Args) => Res {
  return (...args: Args) => {
    // Additional logic can be added here...
    return resolverFn(...args);
  };
}

However, keep in mind that the example with the resolversMap may not work as expected because the overallRankingPlacement function returns a promise while the argument of createResolver does not. To resolve this issue, you can either remove Promise from the return type or pass an asynchronous function to createResolver for aligning the types correctly.

If your goal is to have a version of createResolver that returns an async function, you can modify the function as follows:

function createAsyncResolver<Args extends unknown[], Res>(
  resolverFn: (...args: Args) => Res
): (...args: Args) => Promise<Res> {
  return async (...args: Args) => {
    // Additional async logic can be included here...
    return resolverFn(...args);
  };
}

This updated version will operate seamlessly with your provided resolversMap.

It's important to note that wrapping functions in this manner might not handle overloaded functions effectively. The wrapped function may retain only the last overload, resulting in situations like:

const unfortunatelyNotOverloaded = createResolver(overloaded)
const ok = unfortunatelyNotOverloaded('ok') // inferred type: string
const fail = unfortunatelyNotOverloaded(1)
// ERROR: Argument of type 'number' is not assignable to parameter of type 'string'.

At present, there doesn't seem to be a workaround for this limitation, and it might not be supported in the future.

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

Transforming an object in TypeScript to another object while retaining the properties of the original type

Issue Struggling with TypeScript type casting here. Trying to convert an object of type B to type A, but without carrying over the properties from type B. Inquiry Is there a way to achieve this conversion without explicitly mentioning the otherName prop ...

ANGULAR: Issue with filtering an array by clicking a button is not functioning

I've been attempting to apply a filter to my array by using modulo on the id when clicking multiple buttons. I initially tried using pipe but was advised to stick with .filter(). Despite watching numerous online tutorials, I keep encountering errors o ...

How can I simulate a callback function that was not tested?

Currently experimenting with the method below: startScriptLoad(): void { const documentDefaultView = this.getDocumentDefaultView(); if (documentDefaultView) { const twitterData: ICourseContentElementEmbedTweetWidgetData = this.getTwitterWid ...

Angular's text interpolation fails to update when a value is changed by an eventListener

I am encountering an issue with two angular apps, one acting as the parent and the other as the child within an iframe. The HTML structure is quite simple: <div class="first"> <label>{{postedMessage}}</label> </div> &l ...

The entry for package "ts-retry" could not be resolved due to possible errors in the main/module/exports specified in its package.json file

I encountered an error while attempting to run my React application using Vite. The issue arises from a package I am utilizing from a private npm registry (@ats/graphql), which has a dependency on the package ts-retry. Any assistance in resolving this pro ...

The IntrinsicAttributes type does not include the property 'path' in the Preact router

I am facing a challenge while developing my website using preact router. Every time I try to add something to the router, I encounter an error stating "Property 'path' does not exist on type 'IntrinsicAttributes'." Despite this error, t ...

Steps for importing jQuery to vendor.ts in Angular 2 webpack

Currently, I am in the process of setting up my Angular 2 app using webpack. As I review the vendor.ts file, I notice this specific structure. // Angular 2 import '@angular/platform-browser'; import '@angular/platform-browser-dynamic'; ...

What is the best way to present sorted items on a user interface?

I have a unique Med interface containing properties like drugClass, dosage, and name. Using this interface, I created an array of drugs with different attributes. How can I filter this array by drugClass and then display the filtered data on a web page? ...

The error message indicates that the 'aboutData' property is not found within the 'never[]' data type

What is the correct method for printing array elements without encountering the error message "Property 'post_title' does not exist on type 'never[]'?" How can interfaces be used to define variables and utilize them in code for both ab ...

Is the Inline Partial<T> object still throwing errors about a missing field?

I recently updated to TypeScript version ~3.1.6 and defined an interface called Shop as follows: export interface Shop { readonly displayName: string; name: string; city: string; } In this interface, the property displayName is set by the backend a ...

Error message: The attempted import failed because ' is not exported from the module

I am facing an issue with resolving my problem. In a file named lama.d.ts, I have declared a class using the following code: export declare class lama { // code here } After that, I tried to import this class in another file within the same folder ...

Using TypeScript import statements instead of the <reference path...> in an ASP.NET Core web application: A step-by-step guide

Understanding the Setup I initially had a functional TypeScript Hello World in my ASP.NET Core Web application. To compile TypeScript, I used the NuGet package "Microsoft.TypeScript.MSBuild" Version="4.4.2" along with a tsconfig.json f ...

What is the best way to arrange map elements in a React application?

I am trying to implement filter buttons for low to high rates and high to low rates, but I am having trouble figuring it out. How can I apply the filter to display the data accordingly? The data that needs to be filtered is stored in rate.retail_rate. ty ...

Guide on implementing conditional return types in React Query

In my approach, I have a method that dynamically uses either useQuery or useMutation based on the HTTP method passed as a prop. However, the return type of this method contains 'QueryObserverRefetchErrorResult<any, Error>', which lacks meth ...

The typescript error TS2339 is triggered by the property 'webkitURL' not being found on the 'Window' type

Currently utilizing Angular 2 in a project that is compiled with TypeScript. Encountering an issue when attempting to generate a blob image: Error TS2339: Property 'webkitURL' does not exist on type 'Window' The TypeScript code causi ...

Automatic browser refresh with the `bun dev` command

Currently experimenting with the latest bun platform (v0.1.6) in conjunction with Hono. Here are the steps I followed: bun create hono test-api cd test-api bun dev After running the server, the following message appears: $ bun dev [1.00ms] bun!! v0.1.6 ...

Why does Typeorm consistently encounter insertion failures when attempting to insert into two tables, and why does Math.random() continuously return the same number?

Here is the code snippet I am working with: import { getRepository } from "typeorm"; import { NextFunction, Request, Response } from "express"; import { Users } from "../entity/Users"; import { Verify } from "../entity/Ve ...

Mongodb Dynamic Variable Matching

I am facing an issue with passing a dynamic BSON variable to match in MongoDB. Here is my attempted solutions: var query = "\"info.name\": \"ABC\""; and var query = { info: { name: "ABC" } } However, neither of thes ...

The automatic inference of function argument types and the implementation of conditional types

I'm facing a specific scenario: There's a function that takes in a boolean and returns either a RealItem or an ImaginaryItem. I'm using conditional types to determine the return type based on the boolean argument. type RealItem = { color: s ...

Can you pass a generic type as a parameter for another generic in Java?

Simply provide a generic type like a callback: type FUNC<ARG,RET, F> = (arg: ARG) => F<RET>; type PROMISE<T> = Promise<T>; type IDENT<T> = T; type A = FUNC<number, void, IDENT>; type A_PROMISE = FUNC<number, void, ...