(TypeScript) Generate a type based on the input parameter type

Below is the code snippet I am working with:

const Settings = {
    setting1: 10,
    setting2: true,
};

type S = typeof Settings;

function Process<M extends keyof S>(input: { option: M; value: S[M] }) { }

If I try to call Process with an incorrect type for the parameter, like this:

Process({ option: 'setting2', value: 23 });
                                 // ^ Error: value should be boolean, which it isn't

Query:

I am wondering if it's feasible to generate a new type dynamically based on the argument type of a function, similar to this:

type T5<M extends keyof S> = {
    option: M;
    value: {
        setting1: number;
        setting2: boolean;
    }[M];
}

function ProcessNew<M extends keyof S>(input: T5<M>): void { }
ProcessNew({ option: 'setting2', value: 42 });
                                     // ^ Error: value should be boolean, which it isn't

Rather than defining T5 explicitly, I want it to be created dynamically, taking into account the function's argument type.

I attempted the following approach, but lost type safety for the second parameter:

function NewFunction(arg: Parameters<typeof Process>[0]): void { }
NewFunction({ option: 'setting2', value: 23 });
                                             // ^ No Error, which is a problem

The type of the parameter in this case becomes :

arg: {
    option: "setting1" | "setting2";
    value: number | boolean;
}

I still want to ensure that the type of the second parameter (in this scenario, value) is restricted based on the first parameter.

Playground Link


To clarify further, when we use type T6 = typeof Process, we obtain the following type:

type T6 = <M extends "setting1" | "setting2">(input: {
    option: M;
    value: {
        setting1: number;
        setting2: boolean;
    }[M];
}) => void

... Is there a way to derive a new type like below from the above type? :

type T5<M extends "setting1" | "setting2"> = {
    option: M;
    value: {
        setting1: number;
        setting2: boolean;
    }[M];
}

Answer №1

Regrettably, the answer is negative. Func1 is a generic function and TypeScript is currently unable to deduce generic types.

The parameters of the function type are reduced to their constraints, and we infer from those limitations.

A similar situation occurs when utilizing Parameters<typeof Func1>. The parameters of Func1 are limited to their constraints (e.g., value becomes value: number | boolean) and this specific type is returned.

The only solution is to explicitly use T0<K>, as you have already done.

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

Strategies for effectively searching and filtering nested arrays

I'm facing a challenge with filtering an array of objects based on a nested property and a search term. Here is a sample array: let items = [ { category: 15, label: "Components", value: "a614741f-7d4b-4b33-91b7-89a0ef96a0 ...

typescriptWhat is the syntax in TypeScript for creating a prototype of a multidimensional

I'm currently working on implementing additional methods for a 2D array using TypeScript. Adding methods to a 1D array is straightforward, as shown below: interface Array<T> { randomize(); } Array.prototype.randomize = function () { ...

The trouble with React Navigation encountered with TypeScript: This Entity Cannot Be Invoked

Currently, I'm facing a typescript issue after upgrading to React Navigation 5. The specific error message reads: There is an issue with calling this expression. The union type '{ <RouteName extends "Stack1Screen1" | "Home&quo ...

Show a table row based on a specific condition in Angular

I'm having this issue with the tr tag in my code snippet below: <tr *ngFor="let data of list| paginate:{itemsPerPage: 10, currentPage:p} ; let i=index " *ngIf="data.status=='1'" > <td> </td> <td> ...

Solutions for resolving the issue of not being able to load images when using merged-images in JavaScript

I have a base64 image here and it has already been converted. data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxQSEhUTEhQWFhUXGBoaGBgYGBcXGhgXGBgYGhgbHhoZHiggGholHhgYITEhJSkrLi4uHR8zODMtNygtLisBCgoKDg0OGhAQGi0lICUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0 ...

Combine two streams under certain conditions using RxJs

When working with streams, I am facing a scenario where I have two server calls to make in order to get the required response. However, if the first call returns data, I do not want to execute the second call. I have been struggling to find the proper comb ...

Execute a Typescript function where parameters are passed to another function

In my coding project, I came across a situation where I needed to write a method in Typescript. This method should allow me to run some checks and, if those conditions are met, return the result of another method. What I want is to pass a method along with ...

Efficient configuration for pnpm monorepo with TypeScript, vite, and rollup

Struggling to set up a monorepo using pnpm workspaces with typescript, vite for frontends, and rollup for backend microservices. Here's the current project structure: package.json <== all dependencies reside here tsconfig ...

Creating an Http Service Instance in Angular 2 by Hand

Can the Http Service be initialized manually without needing it as a constructor argument? export class SimpleGridServer { private http: Http; constructor(public options: SimpleServerData) { http = new Http(.../* Argument here */); } } ...

Discover the power of TypeScript's dynamic type inference in functions

Below is a function that selects a random item from an array: const randomFromArray = (array: unknown[]) => { return array[randomNumberFromRange(0, array.length - 1)]; }; My query pertains to dynamically typing this input instead of resorting to u ...

Strategies for efficiently looping through formbuilder.group control elements

JavaScript formGroup = this.fb.group({}); constructor(private readonly formBuilder: UntypedFormBuilder){} ngOnInit() { this.setFields(); } setFields() { this.formGroup.addControl('username', this.fb.control('', Validators.required) ...

Data entered into DynamoDb using typedORM displays inaccurate Entity details

Whenever I add new entries to my local dynamoDb table using typeDORM within a lambda function, it seems to save the record with the incorrect entity information. For example, the GSI1PK GSI1: { partitionKey: 'PRO#{{primary_key}}', ...

What are the ways to recognize various styles of handlebar designs?

Within my project, I have multiple html files serving as templates for various email messages such as email verification and password reset. I am looking to precompile these templates so that they can be easily utilized in the appropriate situations. For ...

Tips for utilizing ngModel with dynamic setter/getter properties

Currently, I am engaged in a project where users can generate applications dynamically. In order to achieve this, I allow components to specify their own properties as shown below. export class InputComponent extends GenericComponent implements OnInit { ...

Angular release 6: A guide on truncating text by words rather than characters

I'm currently enhancing a truncate pipe in Angular that is supposed to cut off text after 35 words, but instead it's trimming down to 35 characters... Here is the HTML code: <p *ngIf="item.description.length > 0"><span class="body-1 ...

Tips for creating a sequelize transaction in TypeScript

I am currently working with sequelize, node js, and TypeScript. I am looking to convert the following command into TypeScript. return sequelize.transaction().then(function (t) { return User.create({ firstName: 'Homer', lastName: ' ...

Observable function encountering difficulties returning nested values

I've been working on a function that returns an observable. test(id: int): Observable<Group>{ this.http.get('test/').subscribe( (result:any) => { resultingVal = Group.fromJson(result.group); }); } Right now, the function ...

The arrow function in Jest is missing a name property

Currently, my setup includes: node.js: 9.8.0 Jest: 23.4.2 ts-jest: 23.1.3 typescript: 2.9.2 While attempting the following in my *.test.ts files: const foo = () => 'bar'; console.log(foo.name); // '' foo contains the name pro ...

What is the process through which Typescript determines the property types of union types?

I am implementing a unique set of types to enable angular form typing: import { FormArray, FormControl, FormGroup } from '@angular/forms'; export type DeepFormArray<T, U extends boolean | undefined = undefined> = T extends Array<any> ...

Sorting TypeScript types by required properties first

Can anyone recommend a plugin or ESLint rule that can automatically sort types by assuming required fields come first, followed by optional fields? Here's an example before: type TExampleSorting = { title?: string; value?: number; text: string; ...