strictNullChecks triggers an issue: the method hasOwnProperty is not available for generic types

I have encountered an issue when trying to enable --strictNullChecks in my code.

After enabling --strictNullChecks, I am getting the error message:

The property 'hasOwnProperty' is missing from type 'T1'.
The property 'hasOwnProperty' is missing from type 'T2'.

function extend<T1, T2>(arg1: T1, arg2: T2): T1 & T2 {
    const result: Partial<T1 & T2> = {};
    for (const prop in arg1) {
        if (arg1.hasOwnProperty(prop)) { // encountering error with --strictNullChecks
            (result as T1)[prop] = arg1[prop];
        }
    }
    for (const prop in arg2) {
        if (arg2.hasOwnProperty(prop)) { // encountering error with --strictNullChecks
            (result as T2)[prop] = arg2[prop];
        }
    }
    return result as T1 & T2;
}

Answer №1

Given that T1 and T2 are unbounded generics, it is possible for either of them to be null or undefined, both of which do not possess the hasOwnProperty method.

To address this issue, you should specify that they extend object:

function mergeObjects<T1 extends object, T2 extends object>(obj1: T1, obj2: T2): T1 & T2 {
// ---------------^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^
    const mergedObj: Partial<T1 & T2> = {};
    for (const prop in obj1) {
        if (Object.prototype.hasOwnProperty.call(obj1, prop)) { // avoids error with --strictNullChecks
            (mergedObj as T1)[prop] = obj1[prop];
        }
    }
    for (const prop in obj2) {
        if (Object.prototype.hasOwnProperty.call(obj2, prop)) { // avoids error with --strictNullChecks
            (mergedObj as T2)[prop] = obj2[prop];
        }
    }
    return mergedObj as T1 & T2;
}

Answer №2

If you're interested in delving deeper into this topic, feel free to check out more information here. Essentially, Typescript isn't aware that your generic type is specifically an Object.

It operates under the assumption, which is reasonable, that it could be any data type – whether that's a string, number, or even null. Therefore, calling hasOwnProperty on those types wouldn't be logical.

To address this issue, you must provide a more precise definition of your generic types.

function extend<T1 extends object, T2 extends object>(arg1: T1, arg2: T2): T1 & T2;

Answer №3

.hasOwnProperty is a crucial property of an Object, which the generic function might not be aware of. To handle this, you can employ T1 extends {} to incorporate those types

function extend<T1 extends {}, T2 extends {}>(arg1: T1, arg2: T2): T1 & T2 {
    const result: Partial<T1 & T2> = {};
    for (const prop in arg1) {
        if (arg1.hasOwnProperty(prop)) { // This may cause an error when using --strictNullChecks
            (result as T1)[prop] = arg1[prop];
        }
    }
    for (const prop in arg2) {
        if (arg2.hasOwnProperty(prop)) { // This may cause an error when using --strictNullChecks
            (result as T2)[prop] = arg2[prop];
        }
    }
    return result as T1 & T2;
}

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

Display the modal in Angular 8 only after receiving the response from submitting the form

I am encountering an issue where a pop-up is being displayed immediately upon clicking the submit button in Angular 8, before receiving a response. I would like the modal to only appear after obtaining the response. Can someone assist me with achieving thi ...

Using TypeScript with React's forwardRef

Here's my code where I have utilized React's forwardRef: interface PropsDummy {} const ProfileMenu = forwardRef<HTMLInputElement, PropsDummy>((props, ref) => { console.log(ref.current); } However, I'm encountering a TypeScript e ...

How to Handle ISO 8601 Dates in Angular2 Using DatePipe?

I recently attempted to implement a basic date pipe in my angular2 application: Registered: {{user.registered | date:'shortDate'}} However, I encountered the following error: Invalid argument '2016-03-28T07:25:40.824Z' for pipe &apos ...

Creating TypeScript atom packages

Has anyone successfully implemented this before? I couldn't locate any assistance for it. If someone could provide references to documentation or existing code, that would be great. I know that Atom runs on Node and that there is a TypeScript compil ...

Switch back and forth between two pages within the same tab on an Ionic 3 app depending on the user's login information

I am seeking a way to switch between two profile pages using the profile tab based on whether the user is a student or tutor in an ionic 3 application. ...

The Dynamic Duo: Typescript and d3

My app utilizes the d3 library with TypeScript code, and I have encountered an issue. To avoid compiler error TS2686, which occurs when d3 refers to a UMD global in a module file, I need to add the following line: import * as d3 from 'd3'; Howeve ...

Navigate to a new tab using this.router.navigate

Is there a way to redirect the user to a specific page with ${id} opening in a new tab, after clicking a button in an angular material dialog box? I want to leave the dialog box open while querying the new page. Currently, the redirect happens but not in a ...

Issues with rendering icons in the Angular Google Maps component

I have been successfully using the Angular Google Maps component. However, I am facing an issue with the custom Icon not appearing. I have set it up as shown below. Can someone please help me troubleshoot why it is not working? mapOptions = { ...

The reducer within ngrx/store fails to trigger

In my project using combineReducers with "@angular/core": "4.4.3" and "@ngrx/store": "4.0.3", I am facing an issue where the reducers are not being detected after dispatching the actions. It could be due to my lack of experience with ngrx/store. You can ...

Combining two objects/interfaces in a deep merging process, where they do not intersect, can result in a final output that does not

When attempting to merge two objects/interfaces that inherit from the same Base interface, and then use the result in a generic parameter constrained by Base, I encounter some challenges. // please be patient type ComplexDeepMerge<T, U> = { [K in ( ...

Conceal Primeng context menu based on a certain condition

I'm struggling to prevent the context menu from showing under certain conditions. Despite following the guidelines in this post, the context menu continues to appear. My goal is to implement a context menu on p-table where it should only show if there ...

The error message from ANGULAR states that it cannot locate the control with the specified path: 'childrenFormArray -> [object Object] -> gender'

I'm currently working on an angular project and facing a challenge in adding multiple children with their age and gender dynamically using reactive forms. Although I can add the form, I am having trouble with the delete functionality as it keeps throw ...

Frequently found items in TypeScript

I need help incorporating a global object in TypeScript for my application. Specifically, I want to have user details available and bindable throughout the entire application after a remote call. Can someone provide an example of how this can be achieved? ...

angular primeng table has a checkbox to select all checkboxes

Is there a way to check all checkboxes in a table when the checkbox in the table header is clicked? I am currently utilizing angular 12 and primeNG table for this functionality. <p-table styleClass="text-sm" [value]="value" [loading] ...

Determining the size of a custom-typed array in Typescript

Can anyone explain how to find the length of a custom typed array? For example: type TMyArray = IProduct[] interface IProduct { cost: number, name: string, weight: number } So, how can we determine the length in this case: const testArr: TMyArray ...

What is the best way to extract data from a directory and store it in an array?

import * as fs from 'fs'; const filesDirectory: string = './src/200k'; function findUniqueValues() { let valuesArr : string[] = []; fs.readdir(filesDirectory, function(error, files){ files.forEach(function(file){ fs.read ...

Error Encountered in Angular 2 Routing - No Matching Routes Found in URL Segment

After spending more than 7 days on this issue, I am at a loss. No matter how hard I try, I can't seem to get it to work. Every time I include the path to the template in the children, it results in an error and crashes the application. Here's th ...

What is the best method to retrieve the unique identifier of the user who is currently logged in

I'm currently facing an issue with accessing the data of the authenticated user in my code and figuring out how to fetch it. I have completed the authentication flow, allowing users to register and login successfully with a token. Even after refreshi ...

bespoke session with Next.js using Next-Auth

I encountered an issue while migrating my JS file to TSX. What I am trying to do is sign in with credentials and customize the session user to my user data. // api/auth/[...nextauth].js import NextAuth from "next-auth"; import Providers from &qu ...

Struggling to transfer data between a component and a template

I have set a variable called MIN_PW above the export class MyComponent. The intellisense recognizes it in my formBuilder, but it is not displaying properly in the UI (UI shows "Password must contain at least characters"). Initially, I had defined the vari ...