employing a parameterized type to accommodate a combination of two diverse items as input

I am facing a challenge with a simple use case and have been unable to find an example that covers it adequately.

The situation is this: I have a function that should accept two different objects that are very similar. Therefore, I want to use a generic type. Here is how the function looks:

const myFunction = <MyGenericType>(arrayOfObjects: MyGenericType[]) => {
  return arrayOfObjects.map((obj: MyGenericType) => ({
    id: obj.id,
    name: obj.name,
    someProperty: obj.someProperty || obj.someOtherProperty,
  }))
}

These are the two types that I could pass as parameters for this function:

type PotentialType1 = {
  id: string
  name: string
  someProperty: string
}


type PotentialType2 = {
  id: string
  name: string
  someOtherProperty: string
}

The issue arises when trying to access properties in myFunction, resulting in an error:

Property X does not exist on type 'MyGenericType'.

This occurs for id, name, and someProperty. While it works fine with primitive types like string or number, complex types pose a challenge.

Any assistance would be greatly appreciated!

Answer №1

Your function is encountering an issue because it lacks information about the structure of MyGenericType. To address this, you need to impose a constraint that indicates certain properties will always be present with this type. It seems like your function requires MyGenericType to belong to one of two specific types. Therefore, you can specify in your generic function that MyGenericType extends a union of these two types:

type PotentialType1 = {
  id: string
  name: string
  someProperty: string
}

type PotentialType2 = {
  id: string
  name: string
  someOtherProperty: string
}

const myFunction = <MyGenericType extends PotentialType1 | PotentialType2>(arrayOfObjects: MyGenericType[]) => {
  return arrayOfObjects.map((obj: MyGenericType) => ({
    id: obj.id,
    name: obj.name,
    someProperty: 'someProperty' in obj ? obj.someProperty : obj.someOtherProperty,
  }))
}

For further exploration and testing, you can use the TypeScript Playground

To handle the properties more effectively, I've modified the assignment of someProperty using a ternary operator. This adjustment allows TypeScript to refine the type of obj instead of flagging errors for missing properties on a type of PotentialType1 | PotentialType2.

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 best way to access the rendered child components within a parent component?

I am seeking a way to retrieve only the visible child components within a parent component. Below is my unsuccessful pseudo-code attempt: parent.component.html <parent (click)="changeVisibility()"> <child *ngIf="visible1"></child> ...

What is the method for accessing the string value of a component's input attribute binding in Angular 2?

In my Angular2 application, I have a straightforward form input component with an @Input binding pointing to the attribute [dataProperty]. The [dataProperty] attribute holds a string value of this format: [dataProperty]="modelObject.childObj.prop". The mod ...

Is there a way to determine if a route, or any of its nested routes, are currently active

Consider the following route examples: <Routes> <Route path="admin"> <Route path="users"> <Route index element={<UserList />} /> <Route path="create" element={<UserDetails ...

How to create classes in typescript without utilizing the class keyword

As someone new to TypeScript, I have a curious question about classes. In pre-ES6 JavaScript, there were no classes. So, naturally, one would think it's possible to avoid using them in TypeScript as well. However, I am struggling to figure out the c ...

Tips for accessing data from a local JSON file in your React JS + Typescript application

I'm currently attempting to read a local JSON file within a ReactJS + Typescript office add-in app. To achieve this, I created a typings.d.ts file in the src directory with the following content. declare module "*.json" { const value: any; ex ...

How can I access other properties of the createMuiTheme function within the theme.ts file in Material UI?

When including a theme in the filename.style.ts file like this: import theme from 'common/theme'; I can access various properties, such as: theme.breakpoints.down('md') I am attempting to reference the same property within the theme ...

Error: The script cannot be compiled with the '--isolatedModules' flag as it is recognized as a global script file

Currently, I am working on building my NextJS app and incorporating Cypress for testing along with Typescript. During this process, I encountered the following error: Type error: 'home.cy.ts' cannot be compiled under '--isolatedModules' ...

I encountered an error with Firebase when attempting to run functions on my local machine

Encountering a Firebase error when running the function locally using emulator in CLI $ firebase emulators:start --only functions Initiating emulators: ["functions"] functions: Using node@8 from host. functions: Emulator started at http://localhost:50 ...

Having trouble triggering the button with querySelector in Angular

I have a dynamic page where I need to click on a button. I tried the code below, but it is not working and not showing any alert. However, if we use the same code in the browser console, it executes and shows an alert. Can someone please suggest how to r ...

Encountering an issue when attempting to save an excel file in Angular 8, receiving an error message that states "

When working with angular 8, I encountered an issue while trying to save an excel file. The error message displayed was as follows: ERROR TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed. at Functi ...

"Exploring the best practice: Defining types in React with Typescript before or after

As a newcomer to typescript, I have noticed that some projects declare the type before the component while others declare it after the component. Can someone explain the differences between these approaches? export type TProps = { item: string; } expor ...

Tips for organizing an array of objects that contain null properties

Here is an array that I need help with: "data": { "risks": [ { "id": "22", "name": true, "surname": 0.5, "age": 0.75, "heigth" ...

Attempt to create a truncated text that spans two lines, with the truncation occurring at the beginning of the text

How can I truncate text on two lines with truncation at the beginning of the text? I want it to appear like this: ... to long for this div I haven't been able to find a solution. Does anyone have any suggestions? Thanks in advance! ...

What is the best way to utilize a tsconfig "alias path" to import an @ngModule along with other definitions?

Repository Link: https://github.com/andreElrico/mono-repo-test Stackblitz Example: https://stackblitz.com/github/andreElrico/mono-repo-test (noop; only to navigate smoothly) Assume the structure below: root/ ├── projects/ │ ├── app1 │ ...

Angular 5 experiencing issues with external navigation functionality

Currently, I am attempting to navigate outside of my application. I have experimented with using window.location.href, window.location.replace, among others. However, when I do so, it only appends the href to my domain "localhost:4200/". Is it possible th ...

Encountering a compilation error when implementing ActionReducerMap in combination with StoreModule.forFeature

In my Angular project, the structure is organized as follows: /(root or repo folder) |_ projects |_ mylib (main library to be exported from the repo) |_ sample-app (created for testing 'mylib' project in other projects) To manage appli ...

Is it Possible for the Number Array Type to Not Be Recognized as an Array?

export class ... { single: any[] = []; multi: any[] = []; view: number[] = [700, 400]; ... <Removed for brevity> } Error Message: It says 'Type 'number[]' is not assignable to t ...

Exploring the features of Typescript involving async/await, Promise, and the use of function

I am currently working on a nodeJS-Express-Typescript project where I need to implement native promises with async/await and also provide default values for functions. Here is a simple example of what I am trying to achieve: sleep(ms: number) { return ...

export keyword in TypeScript disassociates the interface implementation from a class

Currently, I am facing an issue with my files. I have a .ts file that contains a class declaration, and a .d.ts file that contains an interface declaration. An example from the .ts file: class A { constructor() { this.name = "Jo"; } } A ...

Creating a build task in Visual Studio Code with universal TypeScript compiler settings

Our project has the following structure: +-- views +-- viewXXX +-- ts ¦ +-- controller.ts ¦ +-- helper.ts ¦ +-- ... (*.ts) +-- viewXXX.ctrl.js // this is the desired output file +-- viewXXX.c ...