The instantiation of generic types in Typescript

I have been working on a function that aims to create an instance of a specified type with nested properties, if applicable. This is the approach I have come up with so far.

export function InitializeDefaultModelObject<T extends object> (): T  
{
    const root: T = {} as T;
    Object.keys(root).forEach(key =>
    { 
        if (typeof root[key] === 'object') root[key] =  {};
    });
    return root;
}

The issue I am facing is that when I invoke this function, it only returns an empty object {}, instead of an object matching the desired type.

this.ProjectModel = InitializeDefaultModelObject<ProjectModel>();
console.table(this.ProjectModel);

I am unsure if this method is viable at all, and I would appreciate any guidance on what changes are needed to achieve the expected outcome.

Answer №1

It appears that there may be some confusion between TypeScript typings and JavaScript runtime code in your project. Understanding the distinction between the two can greatly benefit you when working on your development projects. TypeScript is primarily a tool to assist during development, providing helpful typings and syntax which are not actually seen by the machine running the code. Once the TypeScript code is compiled down to JavaScript, it closely resembles the original code with all TypeScript-specific elements removed.

Below is an example of how your code looks after compilation:

// my-file.js
export function InitializeDefaultModelObject() {
    const root = {};
    Object.keys(root).forEach(key => {
        if (typeof root[key] === 'object')
            root[key] = {};
    });
    return root;
}


// file-that-imported-my-file.js
this.ProjectModel = InitializeDefaultModelObject();
console.table(this.ProjectModel);

If you have experience with regular JavaScript, you might find that the absence of generics or typings could be causing issues. The current function does not take any parameters and will always output an empty object as a result.

To create a more scalable solution that works for objects of any type in all scenarios, additional considerations need to be made. Here is a modified version of your original code that attempts to address this issue:

export function InitializeDefaultModelObject(originalObj) {
    var sortaCopiedObj = {};
    Object.keys(originalObj).forEach(key => {
        var typeOfField = typeof originalObj[key];
        if (typeOfField === 'object') sortaCopiedObj[key] = {};
    });
    return sortaCopiedObj;
}

For this approach to work effectively, it requires passing in literal objects without prototypes, disregarding non-object field values, and ignoring nested fields of copied object properties. If these limitations are acceptable for your use case, then this solution may suffice. However, dealing with prototypes and nested objects may require a different approach, such as converting the object into a class:

class MyClass {
    a = { innerProperty: {} };
    b = "hey!";
}

// Each instance has the same properties but is unique
var x = new MyClass();
var y = new MyClass();
var z = new MyClass();

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

The marker is not updating in real-time with the actual latitude and longitude on the Google Maps angular

I have been attempting to update the marker in my Angular Google Map in real-time, but unfortunately it is not working as expected. It only displays the initial static data and then fails to update. Despite conducting a thorough search on Google, I have be ...

The most recent version of Angular featuring the powerful Angular-anim

Currently, I am in the process of revamping an application that was initially developed using a combination of jquery, bootstrap, and kendo ui. Moving forward, the application will transition to an angular (2/4) and kendo framework. In the previous setup, ...

The datepicker in Angular Material refuses to open when used within a modal dialog box

I successfully integrated an angular material 2 date-picker into a bootstrap modal form: <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">{{title}}</h ...

Unable to globally override the default font in MUI theme

Objective: My goal is to customize the default font in MUI themes. Issue: Despite reviewing MUI documentation and conducting research on Stack Overflow, I am facing difficulty overriding a custom font globally across my theme. Theme setup: import { creat ...

Mobile Safari on iOS devices is known for its capability to overlay HTML5 <video> on top of everything

Although a similar question was asked 6 years ago without any answers, I am currently facing the same issue. Problem: The <video> tag in my Angular/Ionic application overlaps my image and two buttons in iOS Mobile Safari - no matter what I try! It ...

Isolating a service from a component based on conditions in Angular 5

Within my root module, I have a service that is shared among all components. One of these components is named ComponentX module providers: [ BiesbroeckHttpService ], component constructor(private biesbroeckHttpService: BiesbroeckHttpService){} Som ...

Contact the help desk and receive information that is currently unknown

There are a few issues that I'm struggling to resolve. I am utilizing SwaggerService to fetch data, but the response is coming back as undefined. import {SwaggerService} from '../../services/swagger.service'; export class TestComponent im ...

Obtain the initial URL when initializing an Angular application

In the process of creating an Angular application for a landing page of a SaaS platform, the SaaS redirects to the Angular app using the URL http://localhost:4200/token=<token>. Shortly after, Angular switches to the home component at http://localhos ...

Is it possible for Next.js to retrieve the window size without resorting to a faulty hook call or encountering an undefined window

In my ongoing efforts to dynamically adjust the size of an image within a next.js application to make it responsive to various screen sizes, I have encountered challenges. The different methods I have attempted and observed have resulted in either an inv ...

Error message: Unable to modify the 'cflags' property of object '#<Object>' in Angular CLI and node-gyp

@angular/cli has a dependency on node-gyp, which is evident from the following: npm ls node-gyp <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="16776666653b7477757d7970707f7573562738263826">[email protected]</a> /h ...

What is the proper way to indicate that a function parameter corresponds to one of an Interface's keys?

When working with TypeScript, I am looking for a way to validate that the argument passed to myFunction matches one of the keys defined in MyInterface. Essentially, I want to enforce type checking on the arg parameter as shown below. export interface MyInt ...

Upon attempting to open Google Maps for the second time, an error message pops up indicating that the Google Maps JavaScript API has been included multiple times on this page

Currently, I am utilizing the npm package known as google-maps and integrating it with an angular material modal to display a map. However, upon opening the map for the second time, an error message is triggered: You have included the Google Maps JavaScri ...

Include an additional query parameter called login_hint in microsoft-adal-angular6 directly from an Angular component

Utilizing the provided package https://www.npmjs.com/package/microsoft-adal-angular6 for logging into azure AD has been successful. In the app module, I have configured the extraQueryParamter as shown below: MsAdalAngular6Module.forRoot({` tenant: " ...

Encountering an issue with setting up MikroORM with PostgreSQL due to a type

I'm currently working on setting up MikroORM with PostgreSQL, but I've encountered a strange error related to the type: Here is the code snippet: import { MikroORM, Options} from "@mikro-orm/core"; import { _prod_ } from "./consta ...

Solving the issue of "Property does not exist on type 'never'" in @tusharghoshbd/ngx-datatable Advanced Search with Angular

Currently, in my Angular-13 project, I am working on implementing an Advanced Search feature using @tusharghoshbd/ngx-datatable Below is the code snippet: interface: export interface Merchant { id?: number; merchant_name?: string; account_number?: ...

Filling the text and value array using a collection of objects

Need help with populating an array of text and value using an array of objects in Angular. Below is the JSON data containing the array of objects. Declaration public AuditYearEnd: Array<{ text: string, value: number }>; Assignment - How can I assi ...

Troubleshooting issue: Unable to display data using *ngFor in Angular 4

Currently, I am developing an application that utilizes HttpClient to fetch data from a local JSON file. The JSON file contains images and descriptions, with the images also being local. While I am able to successfully log the data in a local array, I am e ...

What is the best way to retrieve a variable that has been exported from a page and access it in _

Suppose this is my pages/visitor.tsx const PageQuery = 'my query'; const Visitor = () => { return <div>Hello, World!</div>; }; export default Visitor; How can I retrieve PageQuery in _app.tsx? One approach seems to be by assi ...

The FullCalendarModule does not have a property named 'registerPlugins' in its type definition

Currently in the process of integrating fullcalendar into my Angular 15 project and encountering the following error: Error: src/app/views/pages/takvim/takvim.module.ts:18:20 - error TS2339: Property 'registerPlugins' does not exist on type &apo ...

Is there a way to track all Angular form controls that have switched between being enabled and disabled?

Summary: When a FormGroup contains a nested FormControl that changes from disabled to enabled or vice versa, the FormGroup is not marked as dirty. Details: How can you identify all form controls within a FormGroup that have switched between being enabled ...