Setting a property of an object to match the value of its sibling in TypeScript

Is there a way to dynamically type an object field based on the value of its sibling?

Playground link

In this scenario, I have a layout type that resolves into a cell type. Cells can have a layout which should be based on the type of the field.

export interface Layout<T> {
  cells: (Layout<T> | AutoCellProps<T>)[];
}

export type AutoCellProps<T, F extends keyof T = keyof T> = AutoArrayProps<T, F>;

export interface AutoArrayProps<T, Field extends keyof T> {
  dataType: 'Array';
  name: Field;
  layout: Layout<T[Field]>;
}

type formData = {
  section1: {field1: string},
  section2: {field2: string},
}
const layout: Layout<formData> = {
  cells: [
  {
    dataType: 'Array',
    name: 'section1',
    layout: <--- want this to be 
//       Layout<{
//           field1: string;
// }       >
  },
  {
    dataType: 'Array',
    name: 'section2',
    layout: <--- want this to be 
//       Layout<{
//           field2: string;
// }       >
  } 
  ]
}

Answer №1

One interesting approach is to utilize the conditional operator in order to verify the existence of a field, although the inner workings may still seem unclear. Nevertheless, I am sharing the solution here along with the reference link where it was discovered

Rather than using:

export type AutoCellProps<T, F extends keyof T = keyof T> = AutoArrayProps<T, F>

The issue was resolved by implementing the following:

export type AutoCellProps<T, F extends keyof T = keyof T> = F extends keyof T ? AutoArrayProps<T, F> : never;

The answer can be found here -> https://github.com/microsoft/TypeScript/issues/32673#issuecomment-517655996

If anyone comprehends why the type results in a union without the operator, feel free to provide insights in the comments

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

Looking for a way to include an input box within a react-select option dropdown menu

Currently, I am facing a situation where I need to include an input box within my dropdown option menu. The challenge is that I cannot utilize the custom tag creator feature of react select to create a new option with the dropdown. Upon going through the ...

Inactive function

I have a function that inserts my articles and I call this function on my page. There are no errors, but the next function retrieveAllArticles() is not being executed. public saveAllArticles(article) { for(let data in article) { this.db.exec ...

Is it possible to utilize enums as keys in a Json structure?

I am currently utilizing TypeScript in conjunction with Node.js (MEAN stack). My aim is to incorporate an enum within the property/schema of a JSON object. An example of the enum would be: enum KeyEnums { A: "featureA", B: "featureB&qu ...

What is the most effective way to transform values into different values using TypeScript?

If I have a list of country codes and I want to display the corresponding country names in my component, how can I achieve this using props? interface MyComponentProps { countryCode: 'en' | 'de' | 'fr'; } const MyComponent: ...

Exploring matching routes with Next.js + Jest

Issue with Unit Testing MenuItem Component Despite my efforts to achieve 100% coverage in my component unit tests, I have encountered an uncovered branch specifically within the MenuItem component. To offer more insight, here is the parent component that ...

What is the process for creating a TypeScript type that is generic and includes a keyof property?

Looking to create a generic type that can be used as an argument in a function, but struggling with defining strongly typed property names (specificProperties in the example code snippet). type Config<T> = { specificProperties: keyof T[], dat ...

What is the technique for obtaining a complete AST representation of a union type in TypeScript?

Although I am familiar with ts-ast-viewer, I am unsure of how they extract a list of elements from the union. I have experimented with different existing solutions, such as this one, but it appears that most of them are outdated. Some ts.[methods] have be ...

Transmit a sequence of keys to the web browser

I'm having difficulty in sending a Shift key command followed immediately by tilde (~). I've attempted various examples, and here's one that I'm currently working on. I am testing the following scenario - selecting a specific image, t ...

A guide on implementing react-pose alongside @reach/router in a React Typescript project

I'm facing a challenge in my React app as I attempt to convert a JS example using react-pose and @reach/router to TypeScript, but unfortunately, it's not functioning properly. Below are the relevant typings from react-pose: import { ComponentTy ...

An error message occurs in TypeScript when trying to access a property that does not exist in an array

I'm having trouble figuring out this issue... I am receiving data from an API and storing it as an array. I'm attempting to access the data in this format... this.data.results[i].datas[j].dataType However, I keep getting the error "property res ...

How to add a service to a static function in Angular

After incorporating a logger service into my project, I have encountered an issue with using it in NGXS static selectors. The selectors in NGXS are static methods, which prevent me from accessing the logger service injected via Angular DI. Are there any e ...

Tips for sequentially arranging and rearranging an array of numbers, even when duplicates are present

Encountered a perplexing issue that has me scratching my head in an attempt to visualize a solution. Currently, I am working with an array of objects that appears as follows: let approvers = [{order:1, dueDate: someDate},{order:2, dueDate: someDate}, ...

What could be causing the HTTP PUT requests to stop functioning properly after a number of requests?

Currently, I am developing an app for the premier league that allows users to create their own teams, input scores for matches, and view updated team statistics in a sortable table based on the Premier League rules. Issue: I have encountered a problem wi ...

What is the importance of having a reference path for compiling an AngularJS 2 project using gulp-typescript?

I wanted to modify the Angular Tour Of Heros project to utilize gulp from this Github Repository. This is the gulpfile.json file I came up with: const gulp = require('gulp'); const del = require('del'); const typescript = require(&apo ...

What is the best way to eliminate duplicate data from an HTTP response before presenting it on the client side?

Seeking assistance on how to filter out duplicate data. Currently receiving the following response: {username:'patrick',userid:'3636363',position:'employee'} {username:'patrick',userid:'3636363',position:&a ...

Function 'Once' in Typescript with Generics

Currently, I am utilizing a feature called Once() from FP. In TypeScript, I need to define the types for this function but have been struggling with the implementation. Here's what I have attempted so far: const once = <T, U>(fn: (arg: T) => ...

Angular 14: A collection and schematic must be provided for execution to proceed with the process

I've recently started learning angular. After installing the latest version, I created an app called "test" using the command ng new test. Next, I opened the app in Visual Studio Code and tried to create a new component by entering the command: ng g ...

The Express server automatically shuts down following the completion of 5 GET requests

The functionality of this code is as expected, however, after the fifth GET request, it successfully executes the backend operation (storing data in the database) but does not log anything on the server and there are no frontend changes (ReactJS). const ex ...

How do I go about utilizing or bringing in those constants within the Drawerr.js module?

Currently, working with Next.js, I have defined some constants in the Nav.js file: export default function NestedList() { const [value,setValue]=React.useState(); const theme=useTheme(); const isMatch=useMediaQuery(theme.breakpoints.down('lg&apo ...

Injecting shared libraries in a NestJs monorepo system

I am working on a NestJS application that consists of several microservices stored in a single repository following the monorepo approach. The AccessControl module is located in the libs directory and is meant to be shared across multiple microservices. I ...