Attempting to retrieve a specific property based on a given key from either the parent or child object

In my simplified interface, I have:

 interface Author {
       id?: number;
       firstName?: string;
       lastname?: string;
       age?: number;
       coAuthors?:
       [
         {
            id: number;
            firstName: string;
            lastname: string;
            age: number;
         }
       ]
    }

I am attempting to retrieve an object value based on a key:

 const getByKeyName = <T extends {coAuthors: ['coAuthors']}, K extends keyof T>(item: T, key: K) =>
    {

        return item[key] ?? (item.coAuthors?.length ? item.coAuthors![0][key] : 0);  
    };                                                              ^^^^^^^^^  
                                                                    cannot use [key] to index item.coAuthors![0] 

  -----------------------------                     
  getByKeyName(author, 'id');

This leads to the TS error mentioned above, as child is a different object. What would be the best way to address this issue?

Answer №1

To implement the function that can handle a generic type parameter K, constrained by a union of keys common to both the parent author and the first co-author, you can utilize nullish coalescing (??) and optional chaining (?.) techniques to retrieve the first value from either the parent or the first child:

Check out this hands-on example in the TS Playground

function getByKeyName<K extends keyof Omit<Author, "coAuthors">>(
  author: Author,
  key: K,
): Author[K] | undefined {
  return author[key] ?? author.coAuthors?.[0][key];
}

In response to a comment you made:

You mentioned your need to substitute undefined with 0 or an empty string. This handling can be done on the caller side as well.

Indeed, you can apply nullish coalescing at the point of function invocation to set default values when the result is undefined:

TS Playground

const id0 = getByKeyName(author, "id");
//    ^? const id0: number | undefined

const id1 = getByKeyName(author, "id") ?? 0;
//    ^? const id1: number

const id2 = getByKeyName(author, "id") ?? "";
//    ^? const id2: number | string

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

What is the significance of the IRenderFunction interface definition in FluentUI?

Recently diving into TypeScript, I've begun working with DetailsList in Fluent UI. Check it out here: https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist. I'm exploring the onRenderRow property, which is of type IRenderFunct ...

The input tag loses focus after its value is updated using a class method in Angular 8.x

Currently, I am working on integrating a credit card payment method and formatting its number through specific methods. Here is how it is done: HTML <div class="form-group" *ngFor="let formField of cardFields; let cardFieldIndex = index;"> ...

Before accessing the page, please ensure to make a double request

Encountered a weird issue, While inspecting the network tab in Chrome devtools, I noticed that my Vue app is making double requests to the same endpoint :/ Here's a snippet of my code: In the router section, I have a beforeEach function. When I navig ...

Exploring type definition for function arguments in TypeScript and React

There is a high-order component (HOC) designed to store the value of one state for all input and select elements. The output function accepts arguments ({text: Component, select: Component}). An error is displayed while typing an argument: TS2322: Type &ap ...

Is it feasible to create a set of standardized values for an array's properties?

My goal is to restrict the values for a property (or react props in this case) based on the values provided in another property. Firstly, I have my Option interface: interface Option { value: string; label: string; } Next, I define my SelectInputProp ...

Leveraging TypeScript services in both AngularJS controllers and TypeScript controllers

When I converted my AngularJS Service to TypeScript and used the "export" keyword, it became available for import in a TypeScript controller... But how can I still inject it into old controllers? To explain in detail, I am transitioning my controllers to ...

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"> ...

Guide on utilizing TypeScript interfaces or types in JavaScript functions with vscode and jsdocs

Is there a way to utilize types or interfaces to provide intellisense for entire functions or object literals, rather than just function parameters or inline @type's? For example: type TFunc = ( x: number ) => boolean; /** * @implements {TFunc} ...

avoiding browsers loading files that are dropped outside of the designated drop area

Currently, I have set up file drop functionality using ng2 file upload. The issue I am encountering is that when a file is dropped outside of the designated drop area, the browser automatically opens it. Is there a solution to prevent this from happening ...

Warning: Google Map API alert for outdated Marker Class

Working on an application using the Google Maps TypeScript API, I came across a warning message when launching the app -> As of February 21, 2024, google.maps.Marker will no longer be available. Instead, developers are advised to use google.maps.marke ...

How to implement a custom pipe for dynamically changing image URLs in Ionic 3's image tag

I am trying to set authentication headers for images called from an image tag (<img>). To achieve this, I have created a custom pipe named secureimages using the command ionic g pipe secureimages. This pipe intercepts the HTTP requests in an interce ...

The specified property 'length' is not found on type OkPacket within the mysql2 module

In my code example below, I am simply showcasing a specific scenario: this.getCode = (code: string): Promise<codeObject | false> => { return new Promise((resolve, reject) => { pool.query('SELECT * FROM ?? WHERE code = ...

Is there a way to divide the array based on a specific letter in the alphabet using Angular?

I am trying to create something similar to this: "ABCDEF", "GHIJK", "LMNO", "PRSTU", "VYZXWQ", "0123456789" I have a list in alphabetical order; I want names starting with "ABCDEF" to be in one a ...

Steps to access a Request object within a Controller

I am currently working with Express and Typescript, utilizing Controllers for managing requests. In an attempt to create a BaseController that includes the Request and Response objects for each request, I wrote the following code snippet. However, it see ...

Incorporate the Angular framework by using the import statement within the app.module.ts file

Following an upgrade from Angular 1 to Bootstrap with Angular 2 using the upgrade option, encountering an error after importing Angular with systemJS config: map: {... 'angular': 'npm:angular/angular.js' ... } The browser is throwing ...

Determine the character count of the text within an *ngFor loop

I am a beginner in Angular (8) and I am trying to determine the length of the input value that I have created using a *ngFor loop as shown below: <div *ngFor="let panel of panels; index as i" class="panel" [id]="'panel-' + panel.id"> & ...

Problem with execution of TypeScript function from HTML

I have been facing an issue where I am attempting to click a button on an HTML page to trigger a TypeScript function called `getToken()`. Strangely, the function does not seem to get executed when the button is clicked. Surprisingly, I have tested the `get ...

`How to cleverly fake dependencies with symbols in Jest, Vue3, and Typescript?`

I am faced with the following scenario: // symbols.ts - Injection Key defined as a Symbol export const FAQ_SERVICE: InjectionKey<FAQService> = Symbol('FAQService'); // main.ts - globally provides a service using the injection key app.provi ...

Tips for effectively managing index positions within a dual ngFor loop in Angular

I'm working on a feedback form that includes multiple questions with the same set of multiple choice answers. Here's how I've set it up: options: string[] = ['Excellent', 'Fair', 'Good', 'Poor']; q ...

Incorrect Column Header Display in React with Kendo-UI Grid

I have a React application using redux as state manager. In this application we are deciding to use Kendo Ui grids. The first test is Ok but we noticed that the columns are totally wrong. We define only 5 Columns to be displayed in the table but we noticed ...