TypeScript Tutorial: How to retrieve the data type of a deeply nested object

I have a question about extracting the type of a nested object with similar structures. The object in question contains multiple sub-objects that all follow the same pattern.

const VALUES = {
    currentStreak: {
      display: "Current streak",
      value: currentStreak,
    },
    longestStreak: {
      display: "Longest streak",
      value: longestStreak,
    },
    contributionsThisYear: {
      display: "Contributions this year",
      value: contributionsThisYear,
    },
    totalContributions: {
      display: "Total contributions",
      value: totalContributions,
    },
    currentCompany: {
      display: "Working at",
      value: currentCompany,
    },
}

The main keys of the object are working fine, but I'm looking to define types for the individual keys within each object as well.

export type Something = {
  [key in keyof typeof VALUES]: { [key: string]: string | number };
};

How can I properly define the types for each object so that they contain both display and value, where value can be either a string or a number?

Apologies if this is repetitive! I just want to get a clear understanding once and for all.

Answer №1

If Something is meant to represent the type for VALUES, then there is an issue because you are referring to the object you want to type in its own type declaration.

Unless you have an Enum with string values to derive the keys from, it is recommended to type the keys simply as strings:

interface innerSomething {
  display: string
  value: number | string
}

type Something = {
  [key in string]: innerSomething
}

If using an Enum, the syntax should be similar to this:

enum SomethingKeys {
    currentStreak,
    longestStreak,
    contributionsThisYear,
    totalContributions,
    currentCompany
}

interface innerSomething {
  display: string
  value: number | string
}

type Something = {
  [key in keyof typeof SomethingKeys]: innerSomething;
}

Alternatively, instead of declaring an interface, you can define the type of the inner objects within the actual Something declaration like so:

enum SomethingKeys {
    currentStreak,
    longestStreak,
    contributionsThisYear,
    totalContributions,
    currentCompany
}

type Something = {
  [key in keyof typeof SomethingKeys]: { display: string, value: number | string };
}

However, utilizing an interface tends to be more readable and easier to maintain.

Answer №2

Defining the following section is a key step

const ItemData = {
  title: string;
  price: number;
};

export const ItemList = {
  [key in keyof typeof PRODUCTS]: ItemData;
};

Answer №3

console.log(typeof VALUES[keyof typeof VALUES]);

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

Tips for building and implementing Angular URL Parameters for URLs in the form: "component/#/?id=..."

I am currently facing a situation where I have an application with an existing user base. I am looking to avoid disrupting their current links for a smoother transition. However, the previous links are in this format: (server)/viewer/#/?id=12. Please see t ...

Properly passing props to child components in React with TypeScript. Resolve Error ts(2322)

I am facing an issue where my code works perfectly in Javascript, but encounters problems when converted to Typescript. Despite the complexity of the question, it actually boils down to a simple query. I just wanted to share the functional JS code as a sol ...

Using *ngFor to dynamically update the DOM when an array is modified via ngrx

Currently, I am utilizing *ngFor to present values from an array: [ { id: 1, name: 'item1' }, { id: 2, name: 'item2' } ] In the html: <div *ngFor="let item of (items$ | async); trackBy: trackById;&quo ...

How can one define a getter within an interface?

One of my classes is structured like this (only showing a portion here): export class LinkedListNode<t> extends windward.WrObject implements ILinkedListNode<t> { public get next(): LinkedListNode<t> { return this._next === thi ...

What is the best way to avoid passing a value to a component in nextjs?

I'm trying to make this component static and reusable across different pages without passing a parameter when calling it. Is there a way to achieve this while following the official documentation? component: import { GetStaticProps, InferGetServerSid ...

Should we utilize the component @Input as a parameter for the injected service constructor, or should we opt for the ServiceFactory

Within Angular 12 lies a simplified component structured as follows: @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.less'] }) export class ListComponent implements ...

Exploring the power of Vue.js reactivity using Object.defineProperty in a TypeScript environment

Currently, I am in the process of developing a TypeScript class to manage form submissions and handle server errors: export default class Form<Model> { private readonly original: Model private changes: Partial<Model> constructor(d ...

Exporting key/value objects with React components as values in Typescript

I have a .tsx file where I need to export an object containing key/value pairs. Each value is going to be a React component used in another file. While I will have multiple key/value pairs, I'm focusing on just one at the moment. object.tsx import { ...

Encountered an issue while attempting to load the TSLint library for the document within Visual Studio Code

After setting up the latest versions of Visual Studio Code, Node.js, and Typescript on my Windows 10 system, I encountered an issue when trying to utilize TSLint in the terminal. A message appeared stating: Failed to load the TSLint library for the documen ...

Encountered Angular SSR Serve Error: NullInjectorError - StaticInjectorError in AppServerModule with the following reference:

While working on building an application with Angular's SSR and serving it, I encountered a specific error. All services and components have been properly injected. Error: ERROR Error [NullInjectorError]: StaticInjectorError(AppServerModule)[REQUEST] ...

Issues encountered when trying to upload images to Firestore Storage

I am attempting to upload an image and store its URL in a Firestore document. To achieve this, I have the following code snippet: This function uses the device camera to capture the photo. selectImage(): Promise<any> { return new Promise(resolv ...

Component re-rendering and initializing useReducer

I made some revisions to this post. Initially, I shared the entire problem with my architecture and later updated it to focus directly on the issue at hand in order to make it easier for the community to provide assistance. You can now jump straight to the ...

After calling the service, Angular 2 is unable to perform any actions within the subscribe method

I am struggling with what to do after authenticating my user. Once I receive the data, I want to redirect them to the appropriate page based on their role and display their name on that page. I have tried various methods, but it seems like when I try to ca ...

The error message "SyntaxError: Cannot use import statement outside a module" popped up while working with discord.js, typescript, heroku

// Necessary imports for running the discord bot smoothly import DiscordJS, { TextChannel, Intents, Message, Channel, NewsChannel, ThreadChannel, DiscordAPIError } from 'discord.js' type guildTextBasedChannel = TextChannel | NewsChannel | ThreadC ...

Encountering the error "Object potentially undefined" while attempting to activate Cloud Function during document creation

My goal is to automatically create a new authenticated user whenever a new document is added to the "users" collection. The necessary user details will be extracted from the fields "email" and "phone" in the new document. The challenge I am facing is that ...

The Express middleware type cannot be assigned as expected

I'm encountering an error where my first middleware is being red underlined. I can't figure out why it's only happening to the first one. Can anyone provide some guidance on this issue? I'm still quite new to TypeScript. Did I overloo ...

Can you explain the process of utilizing Angular databinding to display nested information?

I'm facing a challenge with databinding when working with nested arrays in multiple timeslots and windows. Despite understanding the basics, I can't seem to make it work no matter how I try different approaches. It's really frustrating not k ...

OpenTok Angular 6 encountered an error with code TS2314 stating that the generic type 'Promise<T>' needs to have 1 type argument specified

Issue in opentok.d.ts File: Error TS2314 npm version: 6.2.0 node: v8.10.0 Angular CLI: 6.2.3 Operating System: Linux x64 Angular Version: 7.0.0-beta.5 @opentok/client": "^2.14.8 ...

Is Intellisense within HTML not available in SvelteKit when using TypeScript?

Having trouble with intellisense inside HTML for a simple page component. Also, renaming properties breaks the code instead of updating references. Typescript version: 4.8.4 Below is the code snippet: <script lang="ts"> import type { Bl ...

Guide to crafting a personalized parameter decorator for extracting the user from a request

Within my express.js application, I have set up an endpoint where I extract the user from the request as shown below: @Put('/:_id') async update (@Request() req: express.Request) { // @ts-ignore const user = req.user; .... } I am intereste ...