What is the method for defining functions that accept two different object types in Typescript?

After encountering the same issue multiple times, I've decided it's time to address it:

How can functions that accept two different object types be defined in Typescript?

I've referred to https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html, and am aware that the standard union operator | isn't ideal for objects as it only includes common elements.

An Example to Illustrate

type Person = {
  name: string;
  age: number;
};

type Pet = {
  owner: string;
};

/*
 * This function should accept two distinct object types as arguments
 */
const randomFunction = (myObject: Person | Pet) => {
  // ISSUE:
  // Property 'age' does not exist on type 'Person | Pet'.
  if (typeof myObject.age !== 'undefined') console.log(myObject.age);
};


Issue: Property 'age' does not exist on type 'Person | Pet'.

How can this be resolved? I want to pass in different object types for a straightforward function.

Is what I'm attempting not in line with TypeScript conventions or is it discouraged?

To eliminate the TypeScript errors, it appears necessary to separate them into distinct functions.

Thank you!

Answer №1

According to @Idruskis, the key is using a TypeGuard.

You can find the detailed solution here: https://example.com/checking-the-type-of-an-object-in-typescript-with-type-guards

type Person = {
  name: string;
  age: number;
};

type Pet = {
  owner: string;
};

// Custom type guard
function isPerson(
  data: Pet | Person,
): data is Person {
  if ((data as Person).age) {
    return true;
  }
  return false;
}

const customFunction = (myObject: Person | Pet) => {
  if (!isPerson(myObject)) return;

  // No issues!
  if (typeof myObject.age !== 'undefined') console.log(myObject.age);
};

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

Issue with AMCharts: DateAxis on my XY graph unexpectedly zooms out to the year 1970 when stacked

Currently, I am attempting to display multiple processes throughout a single day on an AMChart XY axis. Everything seems to be functioning correctly initially, but as soon as I stack the data, the timeline unexpectedly zooms out all the way to 1970. Howev ...

Retrieve the HTML data and save it as page.html, displayed in a VueJS preview

After developing an innovative VueJS-based application for managing front-end content, I am now eager to enhance it with a 'download' button feature. This new functionality will allow users to easily download the previewed and edited content in H ...

How many logical lines of code are in the Ubuntu operating system?

As I develop my web application, it is crucial for me to track the lines of code written in languages such as php, css, html, and JavaScript specific to the /var/www directory. However, when using the command line code counter tool, I find myself tempted ...

What steps can be taken to handle and proceed with any outstanding AJAX requests in the event a

I am currently working on a script to automatically refresh all CSS/JS files that are marked with the attribute-data when any changes occur on the server side. Initially, I attempted to achieve this using php and jquery/javascript but now I am focusing sol ...

SyntaxError: The input on line one ended unexpectedly and was not caught

This issue is commonly associated with messy close parentheses, however, the error is occurring on line 1 of the file! Below is the javascript code from (filename: calculate.js) var colors = new Array(); colors["SILVER"] = -2; ... Although there is m ...

The issue of process.server being undefined in Nuxt.js modules is causing compatibility problems

I've been troubleshooting an issue with a Nuxt.js module that should add a plugin only if process.server is true, but for some reason it's not working as expected. I attempted to debug the problem by logging process.server using a typescript modu ...

Testing NestJS Global ModulesExplore how to efficiently use NestJS global

Is it possible to seamlessly include all @Global modules into a TestModule without the need to manually import them like in the main application? Until now, I've had to remember to add each global module to the list of imports for my test: await Tes ...

Enabling onClick based on conditions

I'm struggling to disable a Link onClick when a certain condition is not met. Attempted to move the logic outside of render using a function, but the button always ends up disabled. Tried CSS to disable click, only to realize that tab and enter can ...

Having trouble sending a FormData object with Axios for a user uploaded file in a React, Node.JS project

My goal is to enable users to upload images to my application, which consists of a React frontend and a Node backend. The process involves sending the uploaded file from the client to the server, followed by making a request from the server to Firebase clo ...

"Encountering issues with Firebase deployment related to function-builder and handle-builder while working with TypeScript

I encountered 4 errors while executing firebase deploy with firebase cloud functions. The errors are originating from files that I didn't modify. node_modules/firebase-functions/lib/function-builder.d.ts:64:136 - error TS2707: Generic type 'Req ...

Annoying scrolling issue arising from using jQuery Buttonset

Dealing with jQuery UI buttons and buttonsets has been quite a challenge for me. Despite searching extensively on this site, I have yet to find a satisfactory solution that works smoothly. My setup includes jQuery rev 1.11.1 and jQuery UI rev 1.9.2. The i ...

What is the best way to display an international phone number using Angular Material V6?

I've been working on a project that utilizes Angular Material V6. My goal is to display international phone numbers with flags in a Material component text box. After some research online, I came across an npm module that achieved this but it was tail ...

Conditional compilation in Laravel Mix allows for specific code blocks to be

I'm currently working on a Laravel project and I need to introduce some conditional statements. Within the root folder of the project, there's a file called module_statuses.json which contains JSON variables like this: { "Module1": true, ...

Tips on sending arguments to functions associated with ...mapActions...()?

After analyzing the passage below export default { methods: { ...mapActions(["updateData", "resetData"]); } } I wanted to include a parameter in the called functions. Unsure of the proper way to do this while still using the ...mapAction() call, ...

What steps should be taken when handling an AJAX request that returns a false result from PHP?

I need help with a form I'm creating that includes a text box labeled "mobileNo" to search for records in a PHP database using AJAX. When a record is found, it should display "Record found". If no record is found and PHP echoes "Record not found", I w ...

Using various Content-Types within a single path with Serverless Next JS

Is it possible to achieve the following scenario using serverless on Vercel with Next JS? I have a route /product/[id].tsx. When a request is sent with the header Accept: text/html, I want it to follow the normal Next JS flow and display a React page. How ...

Strip the CSS styling from an image (the CSS being included in the generated code)

I need to remove the CSS styling from an image, but I can't modify the generated code where it's coming from. My actual code looks like this: <div class="bubble"> <img id="one" src="/static/webupload/MyronArtifacts/images/descarga.png ...

What could be the rationale behind the optional chaining operator not being fully compatible with a union of classes in TypeScript?

Imagine I have a combination of classes: type X = ClassA | ClassB | ClassC; Both ClassA and ClassC have a shared method called methodY. Why is it that I can't simply use the optional chaining operator to call for methodY? class ClassA { methodY ...

What is preventing me from assigning a value of false to my JavaScript variable?

I'm encountering an issue where the articleExists variable is not being set to true on line 6, even though I have used console logs to double check that the if statement containing it is functioning properly. app.post("/articles", function(req, res) ...

Expand all nodes by default in React Sortable Tree

Currently working on a React project and incorporating react-sortable-tree. One problem I'm facing is the lack of an option to automatically expand all nodes by default. Does anyone have any suggestions on how to achieve this? Edit: The options "e ...