Generate a data type automatically based on an Array

Imagine having an imaginary api that provides color values based on user selections.

Consider the following arrays with string values:

const Colors1 = ['red', 'blue', 'purple'];
const Colors2 = ['blue', 'white'];

The api's responses are in the form of objects:

const ColorResponse1 = {
  red: "#ff0000",
  blue: "#0000ff",
  purple: "#aa22ff"
}

const ColorResponse2 = {
  blue: "#0000ff",
  white: "#ffffff"
}

We could manually define the types as follows:

type TColorResponse1 = {
  red: string;
  blue: string;
  purple: string;
}

type TColorResponse2 = {
  blue: string;
  white: string;
}

But is there a way to automatically generate these types based on the input arrays? Something like this:

type TGeneratedColors1 = {[any-color-from-Colors1: string]: string};
type TGeneratedColors2 = {[any-color-from-Colors2: string]: string};

Answer №1

If you want to convert your arrays into unions and then utilize them as keys in your types, you can follow this approach:

const Foods = ['apple', 'banana', 'orange'] as const;
const Colors = ['red', 'green'] as const;

const FoodColors: FoodColorMap = {
    apple: "red",
    banana: "yellow",
    orange: "orange"
}

const ColorCodes: ColorCodeMap = {
   red: "#ff0000",
   green: "#00ff00"
}

type FoodColorMap = { [K in typeof Foods[number]]: string }
type ColorCodeMap = { [K in typeof Colors[number]]: string};

Playground

Answer №2

Here is an alternative method to the previous answer provided.
I propose using the types from the Response1/Response2 objects within the record itself as follows:

const Input1 = ['red', 'blue', 'purple'] as const;
type Input1Tuple = typeof Input1

const Input2 = ['blue', 'white'] as const;
type Input2Tuple = typeof Input2


const Response1 = {
  red: "#ff0000",
  blue: "#0000ff",
  purple: "#aa22ff"
}

const Response2 = {
  blue: "#0000ff",
  white: "#ffffff"
}

type TGenerated1 = Record<Input1Tuple[number], typeof Response1[Input1Tuple[number]]>
type TGenerated2 = Record<Input2Tuple[number], typeof Response2[Input2Tuple[number]]>

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

Is there a way to enable autofill functionality if an email already exists in the database or API within Angular 12?

In order to auto-fill all required input fields if the email already exists in the database, I am looking for a way to implement this feature using API in Angular. Any guidance or suggestions on how to achieve this would be greatly appreciated. ...

Using an array of strings as a key in React with TypeScript to access values from state

import React, { useState } from 'react'; interface PropsInterface { keys: string; // name,email,password } const Poster: React.FC<PropsInterface> = (props: PropsInterface) => { const [state, setState] = useState({ name: ' ...

An unexpected stats.js error occurred while attempting to apply custom styles to the map in AngularGoogleMaps,

My experience with Angular Google Maps has been mostly positive, except for one issue that I have encountered. When attempting to add styles to the map using the styles input attribute, I encounter an error: js?v=quarterly&callback=agmLazyMapsAPILoad ...

Unraveling URLs in JSON with TypeScript

After retrieving a Json string from the BE API, I am parsing it into an array of Products[]. This collection is structured as follows: class Products { ProductId: number; ProductName: string; Price: number; ProductUrl: string; } The issue I' ...

Implementing Angular 2 reactive forms checkbox validation in an Ionic application

I have implemented Angular Forms to create a basic form with fields for email, password, and a checkbox for Terms&Conditions in my Ionic application. Here is the HTML code: <form [formGroup]="registerForm" (ngSubmit)="register()" class="center"> ...

Learn the art of generating multiple dynamic functions with return values and executing them concurrently

I am currently working on a project where I need to dynamically create multiple functions and run them in parallel. My starting point is an array that contains several strings, each of which will be used as input for the functions. The number of functions ...

Utilizing React's idiomatic approach to controlled input (leveraging useCallback, passing props, and sc

As I was in the process of creating a traditional read-fetch-suggest search bar, I encountered an issue where my input field lost focus with every keypress. Upon further investigation, I discovered that the problem stemmed from the fact that my input comp ...

Limit the usage of typescript to ensure that references to properties of 'any' object are verified

I'm facing a situation where I have a JS object called myObject, and it is of type any. Unfortunately, I cannot change the type as it's coming from a library. The issue I encounter is that when trying to access a property from myObject, TypeScri ...

The name is not found when using attribute, but it is found when using extends

Lately, I've encountered difficulties with creating large TypeScript modules, and there's one thing that has been puzzling me. Specifically, the following scenario doesn't seem to work: // file A.ts export = class A { } // file main.ts imp ...

Unable to clear all checkboxes after deleting

In my application, there are 3 checkboxes along with a master checkbox that allows users to select or deselect all of them at once. Everything works fine with the master checkbox until I delete some rows from the table. After deleting data, I can check th ...

Setting the desired configuration for launching an Aurelia application

After creating a new Aurelia Typescript application using the au new command from the Aurelia CLI, I noticed that there is a config directory at the root of the project. Inside this directory, there are two files: environment.json and environment.productio ...

What is the best way to arrange the information in JSON in ascending order and display it in a table format?

I am working with a mat-table and have used GET to display my data. I now want to sort the data in ascending order based on the db-nr from my JSON. Here is an excerpt from my JSON: { "period": 12.0, " ...

The Vue Router hooks are not being activated within the component when utilizing Typescript

I've been pondering this issue for quite some time. Despite my extensive search efforts, I am still unable to figure out why the route-hooks are not working in my component: 1. The component is being loaded from RouterView: <router-view class="z1 ...

Adjust the property to be optional or required depending on the condition using a generic type

const controlConfig = >T extends 'input' | 'button'(config: Config<T>): Config<T> => config; interface Config<TYPE extends 'input' | 'button'> { type: TYPE; label: string; ...

Entering information into fluctuating object fields

Suppose I have a dynamic object with a union type: data: {[key in 'num' | 'str' | 'obj']: number | string | object}; I set the object properties as follows: data.num = 1; data.str = 'text'; data.obj = {}; E ...

Incorporating a particular JavaScript library into Angular 4 (in case the library doesn't have a variable export)

I am attempting to display the difference between two JSON objects in an Angular 4 view. I have been using a library called angular-object-diff, which was originally created for AngularJS. You can view a demo of this library here: Link I have trie ...

Identifying a shift in data model within a component

It seems like there's a piece I might be overlooking, but here's my current situation - I have data that is being linked to the ngModel input of a component, like so: Typescript: SomeData = { SomeValue: 'bar' } Snippet from the vie ...

Angular problem arises when attempting to map an array and selectively push objects into another array based on a specific condition

Setting up a cashier screen and needing an addToCart function seems pretty simple, right? However, I am encountering a strange logical error. When I click on an item to add it to the cart, my function checks if the item already exists in the array. If it d ...

Encountered in the Angular library: NG0203 error stating that inject() should only be invoked within an injection context like a constructor, factory function, or field initializer

Having recently updated my Angular project from version 9 to 15, I encountered the following issue. Any assistance would be greatly appreciated as I have been struggling with it for over 2 weeks. The problem lies within app-lib.module.ts in the Angular li ...

Next.js routes taking precedence over storybook routes

I recently completed a storybook project. Now, I am looking to integrate it with another project built on next.js. The issue is that Storybook and next.js each have their own set of routes. I want to streamline the routing process by utilizing next.js and ...