Discover the type of generic keyof in TypeScript

My types implementation is structured as follows:

type GenericType<T, K extends keyof T = keyof T> = {
    name: K;
    params: T[K]
}

type Params = {
    a: 1;
    b: 2;
}

const test: GenericType<Params> = {
    name: "a",
    params: 2
}

When I create an object like test with the property name: "a", I would like the type of params to be automatically inferred so that params must be 1. Currently, params has type 1 | 2, which corresponds to Params[keyof Params]. However, I believe it should be feasible to restrict the type of params to just 1 based on the value of name, without explicitly specifying the second generic type such as

const test: GenericType<Params, "a">
. Essentially, my desired structure is:

type GenericType <T> = {
    name: keyof T;
    params: T[value of name]
}

Do you think achieving this behavior is possible in TypeScript?

Answer №1

Indeed, if you wish for GenericType<T> to function as a union, you can achieve this by incorporating a mapping technique over the properties of T and then merging that mapped type into a union using a lookup type:

type GenericType<T> = {
    [K in keyof T]: {
        name: K;
        params: T[K]
    }
}[keyof T];

With this adjustment, you should observe the desired functionality:

const test: GenericType<Params> = { // error!
    name: "a",
    params: 2
}

const good: GenericType<Params> = {
    name: "b",
    params: 2
}

You can confirm that the type GenericType<Params> results in

{ name: "a"; params: 1; } | { name: "b"; params: 2; }
, thereby necessitating a precise matching of name with params.

Hope this explanation proves beneficial. Best of luck!

Explore the code in 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

Steps for confirming whether each element in the array includes the specified search string using Typescript and protractor

How can I verify if each element in an array contains a specific search string in Typescript/Protractor? The issue I faced was that the console statements were returning false because they searched for exact matches instead of the search string. Any sugg ...

Transmitting language codes from Wordpress Polylang to Angular applications

I am currently attempting to manage the language settings of my Angular application within WordPress using WordPress Polylang. To achieve this, I have set up the following structure in my Angular application: getLanguage.php <?php require_once(". ...

Using curly braces as function parameters in Typescript

While exploring the content metadata component of Alfresco ADF, I came across this typescript function that has left me puzzled: private saveNode({ changed: nodeBody }): Observable<Node> { return this.nodesApiService.updateNode(this.node.id, nodeB ...

The error message "The export named 'render' (which was imported as 'render') could not be found" appeared

Encountering an error when building a Vue project with TypeScript and Webpack, specifically the "export 'render' (imported as 'render') was not found" issue. Below is the full error code: export 'render' (imported as 'ren ...

Exploring modules alias functionality in TypeScript

Initially, I believed that using path & basePath in tsconfig would allow aliases, but it appears not to be the case. "moduleResolution": "node", "baseUrl": "./src", "paths": { "@api/*": [&qu ...

ES6: The attribute 'selected' is not found on the data type 'Object'

While attempting to convert the JS code from 'AMcharts4 codepen pre selecting areas' into ES6, I encountered an error. Error TS2339: Property 'selected' does not exist on type 'Object'. Here is the code snippet that I am l ...

Issue with the drag functionality of Framer Motion carousel causing malfunction

Attempting to create a basic Image Carousel using framer-motion for added functionality. The goal is to incorporate both buttons and drag control for sliding through the images. Currently, it functions properly, but if the slider overshoots on the last im ...

Converting a text file to JSON in TypeScript

I am currently working with a file that looks like this: id,code,name 1,PRT,Print 2,RFSH,Refresh 3,DEL,Delete My task is to reformat the file as shown below: [ {"id":1,"code":"PRT","name":"Print"}, {" ...

Creating a function that operates according to the input parameter

Imagine a scenario where I am working with the following JS function: function fetchValue(keyName) { return x => x[keyName]; } Is it possible to define fetchValue in such a way that Typescript's type inference automatically determines the outp ...

Troubleshooting Axios errors when using createAsyncThunk function

Can someone help me with handling errors in createAsyncThunk using TypeScript? I attempted to declare the returned type and params type with generics, but when it came to error handling typing, I found myself resorting to just using 'any'. Let& ...

Hiding the keypad on an Android device in an Ionic app when user input is detected

I am currently utilizing the syncfusion ej2 Calendar plugin for a datepicker, but I am only using options such as selecting ranges like today, 1 month, or last 7 days from the plugin itself. The plugin provides dropdown options when the calendar is trigger ...

Teach Typescript to recognize a specific union type within a React component

Imagine I have an object of type: type BulkItem = { id: number; type: 'bulk'; tonnage: number } type RegularItem = { id: number; type: 'regular'; weight: number } export type CartItem = BulkItem | RegularItem // there could be more item ...

Angular 2 date validation rule for dd/mm/yyyy format in forms with reactive functionality

this.seedFundForm = this.fb.group({ multipleSource: this.fb.array([]), amount:[data.amount, Validators.compose([Validators.required, Validators.pattern('[0-9]*'), Validators.maxLength(10)])], date:[data.date, Validators.compose([Valid ...

Issue with NPM: Unable to locate the reference to 'Many' and the namespace '_' from the lodash library

I've been incorporating lodash into my angular2 project. Here are the commands I used: $ npm install --save lodash $ npm install --save @types/lodash Upon installing lodash, warning messages popped up for both the main library and the types: https: ...

Seeking assistance with TypeScript promises

Just starting out with typescript and nodejs, but I've got to tackle some issues in the typescript code. I'm looking to execute an ECS one-off task using Pulumi. I have the documentation on how to run the task from the taskDefinition, which can ...

Attempting to intercept a 401 error in an HTTP interceptor, I aim to refresh my session and then retry the initial request

My goal is to intercept responses returning from the /api, catching them if they are a 401 error, executing a refresh session action, and then retrying the original HTTP call again (while also preventing it from infinitely looping if another 401 error occu ...

Error: Failed to locate package "package-name" in the "npm" registry during yarn installation

While working on a large project with numerous sub-projects, I attempted to install two new packages. However, YARN was unable to locate the packages despite the .npmrc being present in the main directory. ...

Exploring an array in React using typescript

I have a persistent data structure that I'm serving from the API route of my Next.js project. It consists of an array of objects with the following properties: export interface Case { id: string; title: string; participants: string[]; courtDat ...

Unable to proceed with deployment due to the absence of the 'category' property in the '{}' type

Everything seems to be functioning properly - I can add and remove products, all with the properties I specified in the database. However, my deployment for production is being hindered by some errors that I'm encountering. ERROR in src\app&bsol ...

Exploring type definition for function arguments in TypeScript and React

There is a high-order component (HOC) designed to store the value of one state for all input and select elements. The output function accepts arguments ({text: Component, select: Component}). An error is displayed while typing an argument: TS2322: Type &ap ...