Find the appropriate return type for a TypeScript function based on its argument

Is it feasible in TypeScript to infer the return type of a function based on its arguments? This feature would be beneficial when extracting specific properties from, for example, a database query.

Here is an illustration () :

type QueryReturnType = {
  a: string;
  b: number;
  c: boolean;
};

const queryFunc = (): QueryReturnType => {
  return {
    a: 'b',
    b: 1,
    c: true,
  };
};

type Params = {
  [key: string]: keyof QueryReturnType;
};

const takeQuerySubset = (params: Params) => {
  const res: any = {};
  Object.keys(params).map((key) => {
    res[`${key}`] = queryFunc()[params[key]];
  });

  return res;
};

takeQuerySubset({ test1: 'a' }); // { test1: 'b' }

takeQuerySubset({ test2: 'b' }); // { test2: '1' }

takeQuerySubset({ test3: 'b', test4: 'c' }); // { test3: '1', test4: true }

Although the current implementation works, the type of takeQuerySubset is: (params: Params) => any, whereas the objective is to derive a return type dynamically based on the parameters i.e.:

takeQuerySubset({ test1: 'a' }); // should return {test1: string}

takeQuerySubset({ test2: 'b' }); // should return {test2: number}

takeQuerySubset({ test3: 'b', test4: 'c' }) // should return {test3: number, test4: boolean}

This approach ensures that another function utilizing takeQuerySubset can accurately predict the output received.

I attempted using generics to replace any without success. Additionally, note that variables have been renamed e.g. a is now referred to as test1, b as test2, etc.

Answer №1

Utilizing generics in TypeScript allows for flexibility up to a certain extent, as outlined in the documentation available at this link. Alternatively, one can also leverage intersection and union types by referring to this resource. For instance, you can create a type that encompasses both number and string (union type). However, this approach may lead to ambiguity regarding the exact return type of your function for the caller, prompting the need to implement a type guard.

Answer №2

It seems like what you are looking for is this solution:

function extractSubsetFromQuery<T extends Record<string, any>>(params: T): T {
  const result: any = {};
  Object.keys(params).map((key) => {
    result[`${key}`] = fetchData()[params[key]];
  });

  return result;
};

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

Encountering a "Error: Uncaught (in promise): EmptyError: no elements in sequence" due to the presence of multiple Angular 9 Route Resolvers

Why do I encounter an error when attempting to use multiple resolvers in Angular routing? If I remove one of the route resolves, everything works fine. But as soon as I include both, the error occurs. https://i.stack.imgur.com/WFI5C.png https://i.stack.im ...

Incorporating a Script into Your NextJS Project using Typescript

I've been trying to insert a script from GameChanger () and they provided me with this code: <!-- Place this div wherever you want the widget to be displayed --> <div id="gc-scoreboard-widget-umpl"></div> <!-- Insert th ...

Custom-designed foundation UI element with a parameter triggers TypeScript issue

When running this tsx code: import React from "react"; import BaseButton from "@mui/base/Button"; import styled from "@emotion/styled"; export const enum BUTTON_TYPE { MAIN = "main", LINK = "link", } ...

Prevent redirection when submitting and show an error message instead

I implemented a login system where, upon entering the correct username and password, a token is stored in local storage. If there's an error with the credentials, an "Login Unsuccessful" message is displayed. Everything was functioning correctly until ...

Which option is more beneficial for intercepting API data in Angular 6: interfaces or classes?

My API returns JSON data that is not structured the way I need it, so I have to make changes. { "@odata.context":"xxxxxx", "id":"xxxxxxxx", "businessPhones":[ ], "displayName":"name", "givenName":"pseudo", "jobTitle":null, "ma ...

Leverage the Nuxeo client SDK with Angular 6 for seamless integration with RESTClient in

Looking to integrate the Nuxeo ClientSdk with my Angular 6 client to consume its REST API, but facing issues due to the lack of typescript definitions for this JavaScript package. Tried importing the library into my project using the following code snippe ...

Decide on the chosen option within the select tag

Is there a way to pre-select an option in a combobox and have the ability to change the selection using TypeScript? I only have two options: "yes" or "no", and I would like to determine which one is selected by default. EDIT : This combobox is for allow ...

An effective approach to positioning HTML elements at specific X and Y coordinates

I have an innovative project idea! The concept is to enable users to create points by clicking on the display. They can then connect these points by clicking again. However, I am facing a challenge when it comes to creating HTML elements at the exact loc ...

Zod data structure featuring optional fields

Is there a more efficient way to define a Zod schema with nullable properties without repeating the nullable() method for each property? Currently, I have defined it as shown below: const MyObjectSchema = z .object({ p1: z.string().nullable(), p2 ...

Please ensure that the table contains all the records corresponding to the respective days

I am struggling with figuring out how to display a record of classes in my table view. The UX prototype I need to follow is shown https://i.stack.imgur.com/CISYn.png (the days of the week are in Portuguese: horario = time, segunda = Monday, terça = Tuesda ...

Components for managing Create, Read, Update, and Delete operations

As I embark on my Angular 2 journey with TypeScript, I am exploring the most efficient way to structure my application. Consider a scenario where I need to perform CRUD operations on a product. Should I create a separate component for each operation, such ...

Here's how you can transfer the AceEditor value to the component state in ReactJS by utilizing the onClick event of a button

I'm facing a challenge implementing a customized CodeMirror using ACE Editor. I've experimented with incorporating state alongside the 'onClick' button parameter, but I haven't been successful in making it functional. import Rea ...

How to Override Global CSS in a Freshly Created Angular Component

My CSS skills are a bit rusty and I need some assistance with a project I'm working on. The project includes multiple global CSS files that have properties defined for different tags, such as .btn. However, these global CSS files are causing conflicts ...

Combine two arrays into one

When attempting to combine two arrays, the result looks like the image linked below: I want the merged array to resemble the following example: {0: {…}, storedArr: Array(2)} 0: address: "ifanio de los Santos Ave, Mandaluyong, 1550 Metro Manila, Phi ...

Can the return type of a function be determined dynamically at runtime by analyzing a function parameter value?

Let's delve into this concept with an illustrative example! interface Query { foo: any; } interface Mutation { bar: any; } type OperationName = keyof Query | keyof Mutation; const request = async <T>(args, operationName: OperationName): P ...

Combining and linking 3 RxJS Observables in TypeScript and Angular 4 without nesting to achieve dependencies in the result

I have 3 observables that need to be chained together, with the result from the first one used in the other 2. They must run sequentially and each one should wait for the previous one to complete before starting. Is there a way to chain them without nestin ...

Using Typescript with Gulp 4 and browser-sync is a powerful combination for front-end development

Could use some assistance with setting up my ts-project. Appreciate any help in advance. Have looked around for a solution in the gulpfile.ts but haven't found one yet. //- package.json { "name": "cdd", "version": "1.0.0", "description": "" ...

Working with a function in the stylesheet of TypeScript in React Native allows for dynamic styling

When attempting to use variables in my StyleSheet file, I encounter a type error even though the UI works fine. Any suggestions on how to resolve this issue? type buttonStyle = (height: number, width: string, color: string) => ViewStyle; export type St ...

Eslint highlighting the initial function declaration within a Vue script

I'm currently creating a Vue file using a Typescript script, and encountering an unusual Eslint "error." The issue arises on line 15 with this specific complaint: Parsing error: Unexpected token, expected "," Interestingly, this error only occurs wi ...

What is the proper way to enhance properties?

In the process of developing a Vue3 app using Typescript, one of the components is designed to receive data through props. Initially, everything functioned smoothly with the basic setup: props: { when: String, data: Object }, However, I de ...