Proper method for determining return type through the use of `infer`

I need to find out the return type based on input values, like in the code below:

type ReturnType<S> = {
    array: S extends 'number' ? number[] : S extends 'string' ? string[] : never;
    value: S extends 'number' ? number : S extends 'string' ? string : S extends 'object' ? object : never;
}

type FunctionType = {
    array: (_: 'number' | 'string') => void,
    value: (_: 'number' | 'string' | 'object') => void
};

function determineReturnType<
    T extends 'array' | 'value',
    S extends FunctionType[T] extends (_: infer Arg) => void ? Arg: never
>(t: T, s: S): ReturnType<S>[T] {}

() => {
    const x1 = determineReturnType('array', 'number') // string[] | number[]
    const x2 = determineReturnType<'array', 'number'>('array', 'number') // number[]

    const y1 = determineReturnType('value', 'number') // string | number | object
    const y2 = determineReturnType<'value', 'number'>('value', 'number') // number
}

Playground

The above code aims to determine the type of the second argument and the return type from the first argument.

A FunctionType is provided, which includes mutation functions for the second argument. The second argument's type is extracted from the argument of FunctionType using the infer keyword.

However, the compiler struggles to infer the return types of x1 and y1. Is there a way to improve the inference of generics from the second argument?

Answer №1

We can simplify this code using the Parameters utility type, which helps reduce verbosity and resolves the issue (although the reason is unclear).

function test<
    T extends 'array' | 'value',
    S extends Parameters<F[T]>[0]
>(t: T, s: S): Return<S>[T] {}

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

The Concept of Static Block in TypeScript

For the purpose of testing Network Encoding/Decoding Logic, I have implemented a pair of test cases in both Java and JavaScript. These tests utilize Data Providers which essentially consist of various Constants. In my Java test case, I have a Data Provide ...

The utilization of the rest parameter in combination with generics

I encountered an issue with my iteration. The error message "Operator '+=' cannot be applied to types 'number' and 'T'" is showing up. I am puzzled as to why this is happening. let a: number = 1, b: number = 2, c: number ...

The filename is distinct from the file already included solely by the difference in capitalization. Material UI

I have recently set up a Typescript React project and incorporated Material UI packages. However, I encountered an error in VS Code when trying to import these packages - although the application still functions properly. The error message reads: File na ...

The attribute 'checked' is not a valid property for the 'TElement' type

Learning about typescript is new to me. I have a functional prototype in fiddle, where there are no errors if I use this code. http://jsfiddle.net/61ufvtpj/2/ But in typescript, when I utilize this line - if(this.checked){ it presents an error [ts] Pro ...

The parameter cannot be assigned a value of type 'string' as it requires a value that matches the format '`${string}` | `${string}.${string}` | `${string}.${number}`'

I recently updated my react-hook-forms from version 6 to version 7. Following the instructions in the migration guide, I made changes to the register method. However, after making these changes, I encountered the following error: The argument being pass ...

Tips for eliminating contenthash (hash) from the names of JavaScript and CSS files

Google's cached pages are only updated once or twice a day, which can result in broken sites on these cached versions. To prevent this issue, it is recommended to remove the contenthash from the middle of the filename for JavaScript files and eliminat ...

Leverage Typescript to convert string literal types to uppercase

type x = 'first' | 'second' I am looking to create a type y that is similar to this: type y = 'FIRST' | 'SECOND' Here is what I attempted: type x = 'first' | 'second' type y = {[key in x]: key[& ...

Using Angular to dynamically access component properties

Seeking assistance with creating dynamic Tabs in TabView of PrimeNG. The components are displaying properly, but I am unsure how to access their properties. I am following the guidelines provided at https://angular.io/guide/dynamic-component-loader and us ...

Template for typed variable - `ng-template`

How can the parent component correctly identify the type of let-content that is coming from ngTemplateOutletContext? The current usage of {{content.type}} works as expected, but my IDE is showing: unresolved variable type Is there a way to specify the ...

typescript ways to exclude enum values

I am working with enums in TypeScript. enum Status { Cancelled = 'cancelled', Completed = 'completed', Created = 'created' } Now, I need to create another enum that includes only the values Completed and Created. enum S ...

When using `useSWR`, it will return { null, null } for a successful request

When attempting to query the Firebase real-time database using useSWR in my next.js project, I encounter a perplexing issue where both the data and error variables always return as null. import useSWR from 'swr'; const LastSales: NextPage = () = ...

Can you modify a specific column in a table using mat-table in Angular material?

For my project, I am utilizing Angular Material's table to present data in a tabular format. However, due to a new requirement, I now need to enable in-line editing for the last 2 columns alongside highlighting another column when the user clicks on t ...

Advantages of creating model classes in Angular 2 and above

When developing a service for my domain, I discovered that I could easily implement the service using any type like this: list(): Observable<any> { const url = this.appUrlApi + this.serviceUrlApi; return this.http.get(url, { headers: this.he ...

The user interface design transforms as a PDF file is being generated through html2pdf

I am experiencing an unusual problem while using html2pdf to convert an HTML page to a PDF file and download it. The conversion process is successful and the PDF file is downloaded without any issues. However, when I click on a button to generate the file, ...

Why does mapping only give me the last item when I try to map onto an object?

Why does mapping onto an object only give me the last item? Below is the object displayed in the console: 0: {Transport: 2} 1: {Implementation: 9} 2: {Management: 3} When I use ngFor, it only provides the last item const obj = this.assigned_group; // r ...

An error was detected in the card-module.d.ts file located in the node_modules folder within the @angular/material/card/typings directory

Currently, I am working on an angular project using Visual Studio Code as my text editor. When attempting to open the project with 'npm start', an error occurred. The specific error message is: ERROR in node_modules/@angular/material/card/typing ...

Methods for adjusting data based on the current user's login

I'm currently working on integrating a user login feature using Angular 6 for a stock management system. The user credentials are saved in the database, and I have successfully retrieved them into a component (login) for validation. After a successful ...

Creating a subtype in typescript involves specifying values for certain fields and getting rid of any optional members in the type definition

interface Person{ name:string, age:number, gender?:string } interface Employee extends Person{ name='John Doe', age:number } I am trying to achieve the above structure for a person and employee in TypeScript. I am also curious if something simi ...

"Error: Unable to locate module - 'electron-is-dev'" in my web development project using electron, typescript, and webpack

I'm currently working on a project using Electron, Typescript, and webpack. I am planning to integrate react.js into the project. However, when I ran "npx webpack" in the terminal, I encountered an error message. The error stated that the "electron- ...

What is the best way to link labels with input fields located separately in Angular?

Imagine a scenario where labels and form fields are being created in a *ngFor loop, as shown below: app.component.ts export class AppComponent { items = ['aaa', 'bbbbbb', 'ccccccccc'] } app.component.html <div class ...