Access data inside nested objects with specified data type

Imagine the code snippet below:

type Parent = {
   children: Child[]
}

type Child = {
   label: string
}

const parent: Parent = {
   children: [
       { label: 'label1' },
       { label: 'label2' }
   ]
}

How can I use generics to generate a type called Labels that maps the label values as keys with value of any? This should only be applicable to compile-time objects.

type Labels = {
    label1: any,
    label2: any
}

Answer №1

To ensure correct inference of string literals, you can use generics to define Child and Parent, with a generic constraint K extends string:

type Parent<K extends string> = {
   children: Child<K>[]
}

type Child<K extends string> = {
   label: K
}

type Labels<P extends Parent<any>> = P extends Parent<infer K>
  ? { [Key in K]: string } : never;

An efficient way to automatically infer label keys from string literals is by using a helper function to assist when defining the parent value:

function Parent<K extends string>(parent: Parent<K>) {
  return parent;
}

const p1 = Parent({
   children: [
       { label: 'label1' },
       { label: 'label2' }
   ]
})

Create a helper type that leverages inference and object mapping to transform the keys into the Labels type:

type Labels<P extends Parent<any>> = P extends Parent<infer K>
  ? { [Key in K]: string } : never;

type Labels1 = Labels<typeof p1>;

// Labels1 now represents `{ label1: string; label2: string }`

Experience this functionality firsthand on the TypeScript Playground here

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

Quick way to specify type for Observable in Typescript

Exploring Shortcut Declarations When working with TypeScript, I often take a shortcut when declaring object shapes. Instead of creating an interface first and then specifying that the object conforms to that type, I simply do: object: { fizz: boolean, buz ...

Troubleshooting Image Upload Problem with Angular, Node.js, Express, and Multer

While trying to implement the functionality of uploading an image, I have been referencing various guides like how to upload image file and display using express nodejs and NodeJS Multer is not working. However, I am facing issues with getting the image to ...

Error arises when attempting to pass interface props to a component in a React Typescript application

I am currently delving into the world of React js and typescript. As part of my learning process, I have created a demo application that allows users to input their name and age. The app features an ErrorModal that should pop up on the screen whenever inco ...

What's the best way to reset the `react-google-recaptcha` checkbox in a redux application following the submission of a form?

My Redux application consists of two files: LoginForm (which contains the form elements) and LoginFormContainer (which manages form values using Formik). I am facing an issue with resetting the captcha, as the ref is located in the LoginForm file. I attemp ...

Access the $event object from an Angular template selector

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script> <input type="file" #myFile multiple /> <button (click)="onDelete(myFile.event)">DeleteFiles</button> My code snippet is experienci ...

Splitting a td tag into multiple columns dynamically with Angular

I am attempting to dynamically split the table element into separate columns. My desired layout should resemble this: https://i.sstatic.net/C81tg.png The values for name and surname are fixed at 1, but the values for subjects and grades can vary (there ma ...

Can you please provide the Typescript type of a route map object in hookrouter?

Is there a way to replace the 'any' type in hookrouter? type RouteMap = Record<string, (props?: any) => JSX.Element>; Full Code import { useRoutes, usePath, } from 'hookrouter' //// HOW DO I REPLACE any??? type RouteMap = ...

Nextjs 13 brings exciting new features, one of which is the ability to call getStatic

I am working on a Next.js 13 application where I have organized my files in the 'app' directory instead of the usual 'pages'. All pages are statically generated during build time and data is fetched from an external API. https://i.sstat ...

The issue of HTTP parameters not being appended to the GET request was discovered

app.module.ts getHttpParams = () => { const httpParamsInstance = new HttpParams(); console.log(this.userForm.controls) Object.keys(this.userForm.controls).forEach(key => { console.log(this.userForm.get(key).value) const v ...

Issue with Angular: Unable to locate a differ that supports the object '[object Object]' of type 'object'. NgFor is only compatible with binding to Iterables such as Arrays

As someone who is new to Angular, I am facing a challenge while working on my portfolio project. The issue arises when trying to receive a list of nested objects structured like this: "$id": "1", "data": { &quo ...

I am working on an Angular application that includes a dynamic form for an attendance system for employees. I am currently trying to figure out how to generate the JSON data

I have a dynamic form in my reactive attendance system for employees. When I click on submit, I need to generate JSON data like the following: { "user_id": "1", "branch_id": "4", "auth_token": "59a2a9337afb07255257199b03ed6076", "date": "2019- ...

Converting constants into JavaScript code

I've been diving into typescript recently and came across a simple code snippet that defines a constant variable and logs it to the console. const versionNuber : number = 1.3; console.log(versionNuber); Upon running the tsc command on the file, I no ...

The Environment variable in React Native is not functioning when utilizing TypeScript

After installing the react-native-dotenv library, I followed the instructions outlined in the TypeScript guide. I then created a .env file with the following contents: MARVEL_API = <url> MARVEL_PUBLIC_KEY = <public-key> MARVEL_PRIVATE_KEY = &l ...

Utilizing Angular Validators.email with the ability to accept null values

In my .ts file, I have an Angular validator set up like this: this.detailsForm = formBuilder.group( { email: ['', Validators.compose([Validators.email])] }); While this setup works fine, the email validator also applies the required validat ...

The configuration of the property has not been declared (Error: <spyOnProperty>)

Imagine having a MenuComponent @Component({ selector: 'cg-menu', templateUrl: './menu.component.html', styleUrls: [ './menu.component.scss' ] }) export class MenuComponent implements OnInit { menu: MenuItem[]; isLog ...

I'm unable to modify the text within my child component - what's the reason behind this limitation?

I created a Single File Component to display something, here is the code <template> <el-link type="primary" @click="test()" >{{this.contentShow}}</el-link> </template> <script lang="ts"> imp ...

Navigate to a nested page in React router and automatically open a new page whenever there are parameters passed

I am currently using create-react-app to build my project and I am working on implementing dynamic routing. My site has three main pages: Accordion, Movies, and MovieDetail. The Movies page displays a list of movies fetched from swapi. The goal is to have ...

The JSX component cannot be 'FieldArray' at this time

I'm working on a next.js project and using the Formik component. However, I encountered a type error that says "'FieldArray' cannot be used as a JSX component." Can anyone help me resolve this issue? Here is the error message: 'FieldAr ...

Utilizing ngx-bootstrap to enhance Bootstrap dropdown functionality

I initially tried to set up ngx-bootstrap in Angular 2 by using the following command: npm install ngx-bootstrap bootstrap --save Then, I included these lines in angular-cli.json: "../node_modules/bootstrap/dist/css/bootstrap.min.css". In app.compone ...

Is it normal for the Array of Observables to be empty upon initial page load, only to contain content later

Currently, I am working on integrating ngx-infinite-scroll functionality. My goal is to extract the initial 5 posts from my "posts" array and populate them into the "shownPosts" array at the beginning. Subsequently, as the user continues scrolling down, I ...