What is the best way to extract the final values from a complex object and create a new data type containing only

I am working with an object named "Messages" that contains various numeric IDs.

Below is a snippet that represents the structure of the object:

const Messages = {
   Alpha: 1,
   Beta: {
     A: 2,
     B: 3,
   },
   Omega: [
     4,
     5,
     6
   ],
   Zeta: {
     C: 7,
     D: {
       E: 8,
       F: 9,
     }
   }
} as const;

My goal is to define a type that specifically captures these IDs, ensuring secure usage.

Typically, I utilize this object to retrieve the ID in a contextual manner for functions.

For example:

// function translate(id: number): string

const label = translate(Messages.Beta.A);

Since I cannot ascertain valid IDs, I resort to using the generic number type in functions.

Specifications:

  • The IDs are always positive integers.
  • Although modifying the object's structure is feasible, due to its extensive size (2300 lines), I aim to avoid such alterations.
  • As my object is multidimensional, conventional solutions like those referenced below have not proven effective:
    • Create a type constructed with values of an object
    • How to create a type with values from plain object?

Taking my recent plunge into professional use of Typescript, I find myself unsure how to proceed.

Uncertain if my objective is even attainable, I envision generating a union type embodying the highlighted values:

Infered type of example object Messages

An approximation might resemble:

type Values = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
.

Answer №1

If your object consists solely of plain objects and arrays, we can define a type that extracts values from an object recursively:

type DeepValues<T> = T extends object ? T[keyof T] | DeepValues<T[keyof T]> : never;

When used, this may result in extraneous data, but we can filter out only the numbers using the built-in Extract<T, U> utility type:

type T = Extract<DeepValues<typeof Messages>, number>;
//   ^? 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Playground


Here is the tail recursion version:

type DeepValues<T, R = never> = T extends object ? DeepValues<T[keyof T], T[keyof T]> : R;

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

Unable to transfer data from service to component

Just started mastering Angular. I've successfully set up an API with Spring-boot and developed some Angular components to display the data, but unfortunately, nothing is showing up. In my Angular project, I've created a Service to handle all t ...

In Typescript, it is not possible to assign the type 'any' to a string, but I am attempting to assign a value that is

I'm new to TypeScript and currently learning about how types function in this language. Additionally, I'm utilizing MaterialUI for this particular project. The issue I'm encountering involves attempting to assign an any value to a variable ...

Enhance your React application by using a personalized hook that allows you to trigger a function

After creating a custom hook to handle uploads to an AWS S3 bucket, I encountered a small issue. Rather than having the hook execute the logic directly, I decided to create an executable function to return instead. However, I am facing a problem where the ...

Tips for utilizing chodorowicz / ts-debounce effectively

Looking to utilize the debounce function provided by the ts-debounce package (available at here) in my typescript project. However, struggling to find a concrete example of its usage in typescript. Would greatly appreciate any help or guidance on this ma ...

How can we showcase both the output and type errors in Angular?

Is it normal for the UI to show the correct output while displaying a type error in the console? How can this issue be resolved? <tr> <th scope="row">IP address</th> <td>{{deviceinfo['ip-address']}}</td> ...

Uh oh, there seems to be an issue with Angular 8 – it's throwing an error saying "TypeError: Cannot read

I created a website similar to Cat and Mash for selecting a cat at random, but I've encountered an error that is puzzling. Within my JSON object are URLs linking to images. My goal is to randomly display these images without repeating the same image ...

What is the best way to retrieve all SVG objects within a specific area in an Angular application?

I am currently developing an SVG drawing application and have implemented a tool that enables users to select all shapes within a rectangular area. However, I am facing the challenge of detecting the SVG shapes located underneath the selected rectangle. ...

Updating an array using `setState` does not result in the array being updated

I created a component that uses the .map() method to render an array of students and has a button to shuffle and update the display. However, I'm facing an issue where the display does not update every time I click the button. const Home: NextPage = ...

Unit testing a React component that implements a copy to clipboard functionality, using Jest and TypeScript

In order to make sure the correct value is copied to the user's clipboard when they click a button, I have implemented this copy method. By using a ref on the input, I can easily access the right value. protected copyToClipboard() { console.log( ...

What is the best way to bypass TS1192 when incorporating @types/cleave.js into my Angular application?

Using cleave.js (^1.5.2) in my Angular 6 application, along with the @types/cleave.js package (^1.4.0), I encountered a strange issue. When I run ng build to compile the application, it fails and shows the following errors: ERROR in src/app/app.component. ...

Changing array in TypeScript/Angular

I'm attempting to transform an array of strings into an array of key-value pairs, like this: ["x", "y"] transforms into [{"Value":"x"}, {"Value":"y"}] Any tips or guidance would be highly appreciated. Thank you! ...

WebStorm provides alerts for objects, types, and directives within Angular, yet they function properly

Why is WebStorm displaying warnings for objects, types, and directives in Angular Template HTML even though they are functioning correctly? Despite the fact that all types and Angular directives in the HTML structure are working fine within Angular on Web ...

Encountering build issues post upgrade to Angular 9 and Typescript 3.8.3

I recently updated my WebAPI project to Angular 9 and Typescript 3.8.3, but encountered errors during the build process: https://i.sstatic.net/KRzgU.png To try and resolve the issue, I executed various commands such as deleting node_modules and running np ...

Best practice for importing an abstract class into an interceptor

I encountered an issue while trying to import an abstract class into an HTTP interceptor. The error message I received was: 'method' is not a function. I have declared the class within the module as follows: @NgModule({ declarations: [ Roo ...

Avoid retrieving information from Firestore

Hey everyone, I'm struggling to figure out why I can't retrieve data from Firestore. Even after carefully reading the documentation and double-checking the path, I still can't seem to make it work. I'm working with Ionic framework. getC ...

What is the best way to implement a timer using hooks in React?

Just getting started with React! I began my journey last week ;) My first task is to build a timer that includes a reset feature and can count seconds. While the reset function is functioning properly, the timer isn't. Can anyone suggest the best ap ...

"Exploring a New Generation of Angular Chart Libraries in Version

I've been considering upgrading my angular project from version 17 to 18. Currently, I'm utilizing the Plotly.js-dist-min library for creating graphs. However, during the project build (ng build), I've encountered an issue where the plotly ...

Issue in Typescript: "Implementing Partial is restricted to object types or intersection of object types with known members" error occurs when working with classes

Recently, I encountered an issue with my code that was previously working fine until I updated Typescript: class DefaultRouteConfig implements Partial<RouteConfig> { public meta = { layout: LayoutDefault }; } However, after the update, Typescript ...

inject the value parameter into the (click) attribute inside an HTML element

I am currently working with this HTML template: <form #topping (change)="updateTopping(topping)"> <span *ngFor= "let top of toppingOptions"> {{top.name}} {{top.price.toFixed(2)}} <button type="button" value="{{t ...

Removing background from a custom button component in the Ionic 2 navbar

Q) Can someone help me troubleshoot the custom component below to make it resemble a plus sign, inheriting styling from the <ion-buttons> directive? In my navbar, I've included a custom component: <notifications-bell></notifications-be ...