Generate a dynamic interface using properties and options provided in a JavaScript object

Can Typescript support the following scenario:

I have a structure where keys represent properties and values are arrays of options for those properties:

const options = {
  foo: [fooOption1, fooOption2, ...],
  bar: [barOption1, barOption2, ...],
  ...
}

Is there a way to define an interface that maps this structure like so:

interface example {
  foo: fooOption1 | fooOption2 | ...,
  bar: barOption1 | barOption2 | ...,
  ...
}

Answer №1

To start off, make sure to convert your options object into a constant:

const choices = {
  alpha: ['alphaOne', 'alphaTwo'],
  beta: ['betaOne', 'betaTwo']
} as const;

Next, you can define the desired interface by linking each array to a union type:

type ChoicesInterface = {
    [key in keyof typeof choices]: typeof choices[key][number]
}

const yy: ChoicesInterface = {
   alpha: 'alphaOne',
   beta: 'betaThree' // Expected error: 
                         // Type '"betaThree"' is not assignable to type '"betaOne" | "betaTwo"'.(2322)
}

For more information, refer to:

  • Mapped Types
  • TypeScript: Define a union type from an array of strings

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

Strict type inference for the number data type in TypeScript

I am interested in inferring the number type within this function: type Options = { count: number }; function bar<C extends Options>(options: C): C['count'] extends 3 ? 'x' : 'y' {} bar({ count: 3 }) // x bar({ count: ...

Join a subscription and remain subscribed in sequential order

Within the code below, there is a nested subscribe function. It takes a schedule_id and retrieves questions based on that schedule_id. The functionality works correctly, but the order in which getQuestion() is executed is not guaranteed. Schedule IDs: 111, ...

Tips for avoiding the <p> and <br> elements while using a ContentEditable div

Upon pressing the enter key, the editor automatically inserts paragraph and page break elements. What are some strategies to avoid these unwanted elements in the editor? https://i.sstatic.net/r4jU1.png ...

Unlock the full potential of working with TaskEither by utilizing its powerful functionality in wrapping an Option with

After exploring various examples of using TaskEither for tasks like making HTTP requests or reading files, I am now attempting to simulate the process of retrieving an item from a database by its ID. The possible outcomes of this operation could be: The i ...

Avoiding type errors in d3 v5 axis by using Typescript

I am new to TypeScript and I have some code that is functioning perfectly. I believe if I define a type somewhere, d3's generics will come into play? Within my code, I have an xAxis and a yAxis. Both are the same, but D3 seems to have an issue with t ...

The dropdown navigation bar fails to close upon being clicked

I'm currently facing an issue with the navbar in my project. The bootstrap navbar doesn't close automatically after clicking on a link. I have to move my mouse away from the navbar for it to close, which is not ideal. Additionally, I'm worki ...

Limit file upload size to less than 1MB in Angular 2 with typescript using ng2-file-upload

Having issue with my code - I can't upload a file larger than 1mb even though maxFileSize is set to 50mb. Can anyone help me troubleshoot? @Component({ moduleId: module.id, selector: 'NeedAnalysisConsult', templateUrl: 'nee ...

Stretching the Mantine Accordion Section

The Mantine accordion requires that its content be of type Accordion.Item, as indicated in the documentation for the children props. This means that even functions returning AccordionItem will not be recognized. Therefore, only AccordionItem(s) created in ...

"Integrating Orgchart with Typescript in Angular4: A Step-by-Step

mxResources.loadDefaultBundle = false; var bundle = mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) || mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage); // Ensures synchronous requests are handled properly ...

Tips for resolving the issue of dropdown menus not closing when clicking outside of them

I am currently working on an angular 5 project where the homepage consists of several components. One of the components, navbarComponent, includes a dropdown list feature. I want this dropdown list to automatically close when clicked outside of it. Here i ...

The situation I find myself in frequently is that the Angular component Input

There seems to be an issue with a specific part of my application where the inputs are not binding correctly. The component in question is: @Component({ selector : 'default-actions', templateUrl : './default.actions.template.html&a ...

Using TypeScript with GraphQL Fetch: A Guide

I came across a similar question that almost solved my issue, but it didn't quite work for me because the endpoint I'm using is a graphQL endpoint with an additional nested property called query. For instance, if my query looks like this: const q ...

Setting the current date in Angular using TypeScript and storing it in a MySQL database

As I delve into learning Angular, I am focused on practicing with a form. Specifically, I am attempting to include the current date when inputting client records along with their RFC, branch, and cost. Unfortunately, my attempts have been unsuccessful in i ...

Troubleshooting issue with loading local json files in Ionic 3 on Android device

Recently, I've been exploring the process of loading a local JSON data file in my project. I have stored my .json files in the /src/assets/data directory and here is the provider code snippet that I am utilizing: import { Injectable } from '@ang ...

Struggling with TypeScript and JsObservable? Let us assist you!

Having previous experience with JSRender, JSViews, and JSObservables, I recently embarked on a new project using TypeScript. Unfortunately, I am struggling to understand how to properly utilize TypeScript in my project, especially when it comes to referenc ...

The tRPC setData hook is limited in its ability to access all data necessary for optimistic UI updates

As I integrate mutations using tRPC and React Query to optimistically update my UI upon adding a new item, I've encountered an issue. The problem lies in the query I'm updating, which requires specific properties like auto-generated IDs or datab ...

Encountering an error: "Unable to assign the 'id' property to an undefined object while attempting to retrieve it"

I'm running into an issue while attempting to retrieve a specific user from Firebase's Firestore. export class TaskService { tasksCollection: AngularFirestoreCollection<Task>; taskDoc: AngularFirestoreDocument<Task>; tasks: Obs ...

Unraveling the mysteries of an undefined entity

When the variable response is undefined, attempting to retrieve its property status will result in an error: Error: Unable to access property 'status' of undefined const { response, response: { status }, request, config, } = error as A ...

Determine the full location information with the help of Google Maps SDK without the need

My current challenge involves dealing with a list of unformatted and incorrectly written addresses. I am seeking a way to iterate through these flawed strings and generate more organized and accurate addresses using one of the many Google Maps SDKs availa ...

What can possibly be the reason why the HttpClient in Angular 5 is not functioning properly

I am attempting to retrieve data from the server and display it in a dropdown menu, but I am encountering an error while fetching the data. Here is my code: https://stackblitz.com/edit/angular-xsydti ngOnInit(){ console.log('init') this ...