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): Promise<{ data: { [operationName]: T } }> => {

};

The desired outcome is for request to be called like this:

const result = await request<string>({}, 'foo');

In which case, the value of result should resemble:

{
  data: {
    foo: string
  }
}

However, an error is encountered stating

A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type. ts(1170)

It seems plausible that this could be achievable since the type OperationName is known at compile time, thereby allowing the compiler to anticipate all potential return types of request. Unfortunately, I am uncertain about how to implement this!

Answer №1

The focus of this answer is on instructing how to correctly type the function, rather than executing the conversion during runtime.

It is up to you to figure out a way to implement the conversion process yourself, considering factors such as the operation and arguments provided.

One approach suggested here is to utilize a mapped type:

const convert = async <T, O extends OperationName>(args: unknown, operationName: O): Promise<{ data: { [K in O]: T } }> => {

An additional generic parameter O of type OperationName is introduced to remember what was passed as the operation name. This mapped type then associates O with T.

However, there's more to be done. Consider this example when calling the function:

convert<string>(???, "foo")

An error occurs because a value for O is missing. To work around this, we can curry the function:

const convert = <T>() => async <O extends OperationName>(args: unknown, operationName: O): Promise<{ data: { [K in O]: T } }> => {

This modification allows us to specify T separately from O:

convert<string>()(???, "foo")

Explore examples on 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

Oops! Looks like there's an issue with the type error: value.forEach is

I am working on creating an update form in Angular 6 using FormArray. Below is the code snippet I have in editfrom.TS : // Initialising FormArray valueIngrident = new FormArray([]); constructor(private brandService: BrandService, private PValueInfoSe ...

How can I retrieve header values in the canActivate function in Angular?

Depending on the value of userRole received from the header, I need to redirect to different user pages. angular.routing.ts { path: '', pathMatch: 'full', redirectTo: '/login' }, { path: 'user', loadChildren: &apo ...

Develop an "Import Interface" using TypeScript

I have a large project with many files and I believe using an import object would be beneficial. For instance, consider having menu.ts at the top level that every program will refer to: import router from "./router/index"; import controllers from ...

Exploring the canDeactivateFn syntax with Angular Documentation

As a first-year university student, I recently discovered that the canDeactivate() guard in Angular is deprecated, while the canDeactivateFn guard functions without any issues. Admittedly, navigating through official documentation is still new to me. From ...

How can you reposition a component within the dom using Angular?

Just started learning Angular, so I'm hoping this question is simple :) Without getting too specific with code, I could use some guidance to point me in the right direction. I'm currently developing a small shopping list application. The idea i ...

Contrasting @Input with Dependency Injection in Angular 10

Is there a way to pass values from a parent component to a child component without using the @Input decorator? I'm thinking about creating an instance of the Parent class in the constructor (Dependency Injection) and then accessing the variable value ...

Handling events in React using TypeScript

Currently diving into the world of React with Typescript and encountered a challenge involving event handling using the onClick property. I have a react component displaying a list of items from an array, and I aim to log the clicked item in the console. I ...

Troubleshooting problems with resolving deeply nested promises

My approach to utilizing promises has been effective until now. The issue arises when the console.log(this.recipe) returns undefined and console.log(JSON.stringify(recipes)) displays an empty array. This suggests that the nested promises may not be resolvi ...

To handle a 400 error in the server side of a NextJS application, we can detect when it

I'm facing a situation where I have set up a server-side route /auth/refresh to handle token refreshing. The process involves sending a Post request from the NextJS client side with the current token, which is then searched for on the server. If the t ...

If I include the Next.js Image component within a React hook, it may trigger the error message "Attempting to update state on an unmounted component in React."

My UI layout needs to change when the window width changes. However, when I add an Image (Nextjs component) in my hook, I encounter an error message. I am not sure why adding Image (Nextjs component) is causing this problem. The error message is display ...

Supplier for a module relying on data received from the server

My current component relies on "MAT_DATE_FORMATS", but I am encountering an issue where the "useValue" needs to be retrieved from the server. Is there a way to make the provider asynchronous in this case? export const MY_FORMATS = { parse: { d ...

Changing the Value of an Input Element Dynamically in React: A Step-by-Step Guide

In a scenario where I have a component that takes an element, such as <input />, and I need to update its value programmatically after 15 seconds. Initially, I had the following approach in mind: const MyComponent = (myInput: JSX.Element) => { ...

Angular's HttpClient makes sure to wait for the HTTP requests to complete

Initializing arrays with the call this.Reload.All() is causing confusion and breaking the service due to multiple asynchronous calls. I am looking for a synchronous solution where each call waits for its response before proceeding to the next one. How can ...

Exploring the Integration of Graphql Typescript Types in React Applications

I am currently working on a project that involves a React app with a Keystone.js backend and a GraphQL API. Within Keystone.js, I have a list of products and a basic GraphQL query set up like so: import gql from "graphql-tag"; export const ALL_ ...

How can I store the status of checked and unchecked checkboxes in an array of objects using Angular 7?

I have a set of checkboxes with a parent-child structure, and their values are generated dynamically in a loop. When I click the submit button, I want to capture the selected or unselected values in the specified format (as shown in the commented output) ...

Encountering Invalid Chai attribute: 'calledWith'

I am currently in the process of implementing unit tests for my express application. However, I encountered an error when running the test: import * as timestamp from './timestamp' import chai, { expect } from 'chai' import sinonChai f ...

Angular 5 - capturing form inputs - activating event upon selecting suggested values

When I click on suggested values below the input field, the (click)="doSomething()" event doesn't fire. How do I handle this issue? I would like to be able to type something in the input field and then have an event triggered when clicking on the su ...

Unable to create a loop within the constructor to assign API values

I created an export type shown below: export type Program{ key: string; value: string; } An array of values is returned from the API like this: apival = ["abc", "xyz" ...etc] In my component's constructor, I am implementing the f ...

Issues with identifying the signature of a class decorator arise when invoked as an expression

I've been following this coding example but I'm running into issues when trying to compile it. Any suggestions on how to troubleshoot this error? import { Component } from '@angular/core'; function log(className) { console.log(class ...

The error TS2339 is indicating that there is no property called myProperty on the type SetStateAction<User>

I'm encountering a TypeScript error while working with React that's leaving me puzzled: <html>TS2339: Property 'subEnd' does not exist on type 'SetStateAction&lt;User&gt;'.<br/>Property 'subEnd' d ...