Strategies for managing complex and deeply nested union types

Trying to extract and display data from the balanceModel parameter in the function is proving challenging due to deep nested models. Any help in identifying any flaws in the types below would be greatly appreciated.

Explore a live example of this logic on CodeSandbox: https://codesandbox.io/s/bold-meitner-vxto9

type BalanceModelAMDRType = {
  from: number;
  to: number;
  [index: string]: number;
};
type BalanceModelSectionType = {
  DRI: {
    AI: number;
    AMDR: BalanceModelAMDRType;
    EAR: number;
    RDA: number;
    UL: number;
    unit: string;
    [index: string]: string | number | BalanceModelAMDRType;
  };
};

type BalanceModelProgressSectionType = {
  DRI: {
    recommended: number;
    unit: string;
    [index: string]: string | number;
  };
};

type BalanceModelType = {
  energy: BalanceModelSectionType;
  [index: string]: BalanceModelSectionType | BalanceModelProgressSectionType;
};

function _updateEnergyDependentSections(
  balanceModel: BalanceModelType,
  energy: number
): void {
  const sections = [`mock`, `data`];

  sections.forEach(sectionName => {
    if (balanceModel[sectionName]) {
      const { DRI } = balanceModel[sectionName];

      Object.keys(DRI).forEach(DRIName => {
        switch (true) {
          case sectionName === `mock`:
            const AMDR = DRI[DRIName];

            Object.keys(AMDR).forEach(AMDRValueName => {
              const AMDRValue = AMDR[AMDRValueName];
              AMDR[AMDRValueName] = Math.round(
                AMDRValue * conversionMultiplier
              );
            });
            break;

          case sectionName === `data`:
            DRI[DRIName] = Math.round(DRI[DRIName] * conversionMultiplier);
        }
      });
    }
  });
}

Answer №1

If the issue is understood correctly.

const AMDR = DRI[DRIName]

can be of type

string | number | BalanceModelAMDRType
.

In the mock section, it should be of type BalanceModelAMDRType, and in the data section, it should be a number.

If you are certain about the type at that moment, you can use as type" like this:

const AMDR = DRI[DRIName] as BalanceModelAMDRType; or
const AMDR = DRI[DRIName] as number;

If you are unsure about the types in those instances, you will need to use a type guard (if statement).

if(typeof AMDR !== 'number' or typeof AMDR !== 'string'){ // AMDR is BalanceModelAMDRType }
if(typeof AMDR == 'number'){ //AMDR is number }

You can also add a property to a type (interface) for identification purposes:

type BalanceModelAMDRType = {
  type: "AMDR";
  from: number;
   to: number;
  } & { [index: string]: number };

Additionally, you can create a type guard function:

function isBalanceModelAMDRType(v: any): v is BalanceModelAMDRType {
  return "type" in v && v.type === "AMDR";
}

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

Make sure to include `jquery` in the types section of your tsconfig file

I've encountered an issue while trying to use jQuery in my Angular-TypeScript project. After installing jquery using "npm install @type/jquery", I am receiving the following error when trying to serve: Error TS2592: Cannot find name '$'. Is ...

Exploring the variance between inlineSourceMap and inlineSources within the TypeScript compiler options

According to the documentation: --inlineSourceMap and inlineSources command line options: --inlineSourceMap will include source map files within the generated .js files rather than in a separate .js.map file. --inlineSources allows for the source .t ...

Exploring a different approach to utilizing Ant Design Table Columns and ColumnGroups

As per the demo on how Ant Design groups columns, tables from Ant Design are typically set up using the following structure, assuming that you have correctly predefined your columns and data: <Table columns={columns} dataSource={data} // .. ...

The issue with Ionic 2 and Angular 2 is that the http Headers are not getting included in the request

I'm currently working with the latest beta release of Ionic and I've encountered an issue with sending headers along with an HTTP POST request to my API server. The code snippet I used is as follows: ** Ionic version - Beta-8 & Angular version -r ...

What is the syntax for declaring a boolean or object type?

Is it possible to create a variable in TypeScript that can hold either true/false or an object of booleans? I'm still learning TS and would like some input on this syntax. variableA: { a: boolean, b: boolean } | boolean I found a workaround for now, ...

What is the best way to initialize an array with values in a Typescript constructor?

I've attempted the following: class PhraseService phrasePosShortNames: [{ id: number, name: string }]; phrasePosNames = [ { id: 0, longName: '#', shortName: '#' }, ...

VS code shines a spotlight on Jasmine functions within Angular 6

Recently, I made the switch to Angular 6.0. However, in VS Code, all jasmine functions are being highlighted as unknown even though they work fine and the tests run successfully. How can I make intellisense recognize Jasmine? In previous versions, a worka ...

Utilizing Protractor's advanced filtering techniques to pinpoint the desired row

I am trying to filter out the specific row that contains particular text within its cells. This is my existing code: private selectTargetLicense(licenseName: string) { return new Promise((resolve => { element.all(by.tagName('clr-dg-tab ...

Can Tailwind Merge function apply to Tailwind classes with prefixes?

When dealing with conflicts, I am required to use tailwind classes with a prefix. However, the tailwind merge functionality does not seem to work with prefixed classes such as tw-flex-1 instead of flex-1. During debugging, I attempted the following: conso ...

Exploring Mixed Type Arrays Initialization in Typescript using Class-Transformer Library

In my class, I have a property member that is of type array. Each item in the array can be of various types such as MetaViewDatalinked or MetaViewContainer, as shown below class MetaViewContainer{ children: (MetaViewDatalinked | MetaViewContainer)[]; ...

Issue encountered while managing login error messages: http://localhost:3000/auth/login net::ERR_ABORTED 405 (Method Not Allowed)

I am working on the /app/auth/login/route.ts file. import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export async functi ...

Exploring the Concept of Dependency Injection in Angular 2

Below is a code snippet showcasing Angular 2/Typescript integration: @Component({ ... : ... providers: [MyService] }) export class MyComponent{ constructor(private _myService : MyService){ } someFunction(){ this._mySer ...

Ways to display a component with different initial state when needed?

Within my application, I have a specific component that independently manages its state using the useState hook. However, I am encountering an issue where I need to conditionally render multiple instances of this same component: const PaymentScannerView: R ...

Angular service is able to return an Observable after using the .then method

I am currently facing an issue with retrieving the authentication status in a service method. Everything seems to be working fine except for the return statement. I am struggling with the usage of .then inside .map and I am unable to figure out how to retu ...

Error in Typescript due to delegate function not being recognized post minification

Here is a code snippet that uses delegate: <pre> $.ajax(this.validateURL, { type: "post", url: this.validateURL, data: JSON.stringify(i), contentType: "application/json; charset=utf-8", dataType: "json", success: i => t.pro ...

Problems with the duration of Shadcn Toasts (Inspired by the react-hot-toast library)

Within a 13.4 Nextjs project (app router), utilizing Typescript and TailwindCSS. I am currently exploring the usage of toasts provided by the remarkable shadcnUI Library, which draws inspiration from react-hot-toast while adding its own unique flair. Imp ...

Guidance on Sending Slider Values to a React Form within a Component

I am currently developing a React application using Typescript. One of the features I implemented is a multi-step form, where each form page is its own component and fields are individual components as well. While I can successfully view data from Text Fie ...

Can you conduct testing on Jest tests?

I am in the process of developing a tool that will evaluate various exercises, one of which involves unit-testing. In order to assess the quality of tests created by students, I need to ensure that they are effective. For example, if a student provides the ...

Setting up the cypress-grep plugin version 3.1.0 on Cypress v11.01: A Step-by-Step Guide

Cypress Version 11.0.1 Node Version 16.16.0 Package Manager Yarn version 1.22.19 Operating System Windows 10 Pro Version 21H2 To practice using the Cypress grep plugin, I have set up a test project called cypress_grep_test_project. I have modified som ...

Is your Angular2 form page experiencing reloading issues?

I am currently incorporating Angular2 into my project. I am facing an issue where the page keeps refreshing, and I'm unable to determine the cause. Below is a snippet of my form: <form> <div class="form-group"> ...