What is the best way to design a type that exclusively allows for a list of properties from a different type?

My current challenge involves creating a "FormField" generic type that will only accept a tuple of properties' names/values from a specified type, along with additional properties like "checked".

For instance:

const formProperties: FormField<User> = [{name: "name", value: "Toto", checked: false}, {name: "age", value: 30, checked: true}]` with User defined as `interface User { name: string; age: number;}` or `const formProperties: FormField<House> = [{name: "width", value: 100, checked: true}, {name: "height", value: 50, checked: false}]` with House defined as: `interface House { width: number; height: number; }

I am aware that I could simply use:

{name: string; value: string | number | CustomType }[]

but that approach limits the ability to determine the type of "value".

Attempts with mapped types have not yielded success either.

type FormField<T> = {[Property in keyof T]: T[Property]};

Answer №1

Resolution

type FormDataFieldItem<T, Key extends keyof T> = {
  field: Key;
  data: T[Key];
  isSelected: boolean;
}

type FormDataField<T> = {
  [K in keyof T]: FormDataFieldItem<T, K>;
}[keyof T][];

What is the process here?

To simplify the structure, I have separated a single list item into its own type called FormDataFieldItem. This organization not only enhances readability but also provides flexibility for future modifications.
The FormDataFieldItem type requires two generic parameters:

  • T: represents the complete object for mapping the specified Key type
  • Key: maps the type of the field property and the type of the data property

We utilize the FormDataFieldItem type within our FormDataField type to initially create a new object by pairing each key of the object (T) with the respective FormDataFieldItem. Subsequently, we iterate through all keyof T's to generate a Union of all probable FormDataFieldItem's. Ultimately, we anticipate a list comprising these unions (indicated by the final []).

Is it functional?

You can validate this using the values you provided in your explanation. Interactive TypeScript Playground link

interface Person { name: string; age: number; }

const formDataFields: FormDataField<Person> = [
  // valid
  { field: "name", data: "John", isSelected: true },
  // valid
  { field: "age", data: 25, isSelected: false },
  // invalid
  { field: "name", data: 30, isSelected: true },
];

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 selecting specific types from a list using generic types in TypeScript

Can anyone assist me in creating a function that retrieves all instances of a specified type from a list of candidates, each of which is derived from a shared parent class? For example, I attempted the following code: class A { p ...

Visual Studio encountering an error with AngularJS TypeScript integration

Hey everyone! I recently installed the angularjs.typescript and jquery.typescript packages from NuGet. However, I'm encountering errors in Visual Studio, as shown in the attached image. I'm using VS 2013 U4 and have updated all extensions and p ...

When working with the Sequelize-Typescript One To Many Association and Repository, a situation may arise where the query returns only one child entity even though there are multiple

Dealing with Sequelize-Typescript, I recently encountered the one-to-many association involving "Album" and "Photos" entities. Each "Album" can have multiple "Photos". Below are the entity codes for reference: Album.ts ` @Table({ timestamps: true, de ...

Authentication checkpoint within an Angular application using a JWT cookie

After searching extensively, I was unable to find a question that directly addresses my specific concern. Currently, I am working on a project involving an angular application that utilizes jwt and http-only cookies for authentication. In order to authenti ...

Is it possible to transform a webpack bundled javascript file into typescript source code?

Is it possible to decompile a webpack-bundled JavaScript file into TypeScript source code? I have a bundle.js file that was bundled using webpack, but the original source code files were accidentally deleted. I am hoping to reverse engineer the bundle.js ...

angular2 and ionic2 encounter issues when handling requests with observable and promises

I am attempting to trigger an action once a promise request has been resolved, but I'm having trouble figuring out how to achieve this. After doing some research, I learned that Ionic2 storage.get() returns a promise, and I would like to make an HTTP ...

A guide on transforming JSON data to an array format where nested arrays are encapsulated within objects using curly braces instead of square brackets in TypeScript

Retrieve data from a REST API in the following format: { "ProductID":1, "Category":[ { "CategoryID":1, "SubCategory":[ { "SubCategoryID":1, } ] } ] } I need to t ...

During the process of running mocha tests, an error is encountered stating that a "reflect-metadata shim is necessary when utilizing class decorators."

Recently, I wrote a Mocha test case using Chai in Typescript and followed the steps outlined in this article here to install all the necessary dependencies. However, when trying to run the test cases with "npm test", I encountered the following error mess ...

The compilation time of Webpack and Angular 2

My compile time is currently at 40 seconds and I'm looking for ways to speed it up. I attempted setting the isolatedModules flag to true in the configuration but encountered an error: error TS1208: Cannot compile namespaces when the '--isolated ...

Can the internal types be accessed through Assembly.GetExportedTypes()?

Similar Question: Understanding Assembly.GetExportedTypes and GetTypes Do internal types become visible when using the method Assembly.GetExportedTypes()? What happens if the call is made from an assembly with an InternalsVisibleToAttribute? ...

Angular: use an icon in place of text

Consider this scenario where a component.ts file looks like the following: @Input() studentHeader?: BaseStudent; get studentText() { if(this.studentHeader) { return this.studentHeader.nr + ' - ' + this.studen ...

Is there a TypeScript equivalent to NSUserDefaults or SharedPreferences?

Just getting started with Angularjs-2.3 TypeScript and I have a specific scenario where I need to save the userId in the app so it can be accessed anywhere within the app. If I were developing for Android or iOS, I would typically use NSUserDefaults and S ...

Error Encountered: Unable to locate angular/core module in Angular 2

I have encountered an issue while setting up a new Angular2 app from the quickstart folder on the Angular website. Despite following all suggested solutions, I am still facing errors. After running npm install, everything seems fine as I can see my node_mo ...

Trying to automatically select a checkbox upon page load in Angular 6

When the page loads, I want to automatically check a checkbox. Here is my component: var user = ViewprojectComponent.featuresList1; this.rules_id = user[0]; for(let i = 0; i <= this.rules_id.length; i++) { var checkedOn1 = this.rules_id[i]; this.Ru ...

Ignore a directory during TypeScript compilation

When writing code in Atom, the use of tsconfig.json to include and exclude folders is essential. For optimal intellisense functionality, the node_modules folder must be included. However, when compiling to js, the node_modules should not be compiled. To ac ...

Angular: Retrieving the Time Format from the Browser

Is there a way to retrieve the time format from the operating system or browser within Angular in order to display time in the user's preferred format? I have attempted to search for a solution, but have come up empty-handed. Thank you in advance! ...

Is it possible to dynamically assign a CSS class to a DOM element during a drag operation while the mouse button is held down?

I am currently working on developing a unique pathfinder visualizer. My progress so far includes creating a grid of size 16x45 using the function below: export const drawBoard = () => { const boardContainer: HTMLDivElement | null = document.querySelec ...

How can you verify the data type of an object without resorting to type guarding

I have a situation where I need to deal with different types of objects. export interface A { links: number name: string } export interface B { cat: boolean name: string } Initially, I considered using this method: const IsTypeB = (obj: any): obj ...

Tips on utilizing JavaScript to retrieve all HTML elements that have text within them, then eliminating the designated element and its descendants

Simply put, I am looking to extract all the text-containing elements from the HTML and exclude specific elements like 'pre' or 'script' tags along with their children. I came across information suggesting that querySelectorAll is n ...

Inserting a pause between a trio of separate phrases

I am dealing with three string variables that are stacked on top of each other without any spacing. Is there a way to add something similar to a tag in the ts file instead of the template? Alternatively, can I input multiple values into my angular compo ...