Overloading constructors in Typescript

I am struggling to convert these Java constructor overloads to Typescript:

public QueryMixin() {
    this(null, new DefaultQueryMetadata(), true);
}

public QueryMixin(QueryMetadata metadata) {
    this(null, metadata, true);
}

public QueryMixin(QueryMetadata metadata, boolean expandAnyPaths) {
    this(null, metadata, expandAnyPaths);
}

public QueryMixin(T self) {
    this(self, new DefaultQueryMetadata(), true);
}

public QueryMixin(T self, QueryMetadata metadata) {
    this(self, metadata, true);
}

public QueryMixin(T self, QueryMetadata metadata, boolean expandAnyPaths) {//...}

I have attempted to create these constructors by referencing the examples provided, but I am unable to resolve the issue...

Do you have any suggestions?

constructor();  <<<1>>>
constructor(metadata: QueryMetadata);
constructor(metadata: QueryMetadata, expandAnyPaths: boolean);
constructor(self: T);
constructor(self: T, metadata: QueryMetadata);
constructor(selfOrMetadata: T | QueryMetadata, expandAnyPaths: boolean) {
    this.self = selfOrMetadata;  <<< PROBLEM HERE
    this.metadata = selfOrMetadata;  <<< PROBLEM HERE
    this.expandAnyPaths = expandAnyPaths;
}

The compilation message at <<<1>>> states:

Overload signature is not compatible with function implementation.

Answer №1

To achieve the constructor overloads you desire, it is necessary to perform type checking in order to make it possible. While I am not aware of the exact structure of QueryMetadata, the concept can be grasped from this self-contained example.

A custom type guard is utilized here to differentiate between union types:

interface QueryMetadata {
    metadata: string;
}

function isQueryMetadata(obj: any): obj is QueryMetadata {
    return (obj && obj.metadata);
}

class Example<T> {

    private metadata: QueryMetadata;
    private self: T;
    private expandAnyPaths: boolean;

    constructor(metadata: QueryMetadata);
    constructor(metadata: QueryMetadata, expandAnyPaths: boolean);
    constructor(self: T);
    constructor(self: T, metadata: QueryMetadata);
    constructor(selfOrMetadata: T | QueryMetadata, expandOrMetadata: boolean | QueryMetadata = false) {
        if (isQueryMetadata(selfOrMetadata)) {
            this.metadata = selfOrMetadata;
        } else {
            this.self = selfOrMetadata;
        }

        if (isQueryMetadata(expandOrMetadata)) {
            this.metadata = expandOrMetadata;
        } else {
            this.expandAnyPaths = expandOrMetadata;
        }
    }
}

Factory Method Approach

If starting anew, utilizing a factory method to construct your class may be preferable...

interface QueryMetadata {
    metadata: string;
}

class Example<T> {

    private metadata: QueryMetadata;
    private self: T;
    private expandAnyPaths: boolean;

    protected constructor() { }

    static fromMetadata<T>(metadata: QueryMetadata, expandAnyPaths: boolean = false) {
        const example = new Example<T>();
        example.metadata = metadata;
        example.expandAnyPaths = expandAnyPaths;
    }

    static fromSelf<T>(self: T, expandAnyPaths: boolean = false) {
        const example = new Example<T>();
        example.self = self;
        example.expandAnyPaths = expandAnyPaths;
    }
}

const example1 = Example.fromSelf('Some Value');
const example2 = Example.fromSelf('Some Value', true);
const example3 = Example.fromMetadata({ metadata: 'val' });
const example4 = Example.fromMetadata({ metadata: 'val' }, true);

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

Transforming data objects into simplified interfaces using Typescript

Issue Explanation Current data: { "field1": "value", "field2": 3, "field3": true, "extraField": "toRemove" } An interface is defined as follows: export interface MyInterface { field1: string; field2: number; field3: boolean; } Objective ...

The React component fails to trigger a re-render even after updating its internal state

I'm new to React and I can't figure out why my code isn't working as expected. I have a dropdown menu where clicking a link should make the menu disappear. The onClick event is triggered, but the UI doesn't update. Link with onClick Ev ...

Issue with updating array of objects in Typescript when working with dates

In my TypeScript function, I am working with query parameters to update an object based on certain conditions. The function loops over the existing set of query parameters and updates the object if it finds a matching parameter name. It's important t ...

Error in Angular 2.0 final version: Unable to access the 'injector' property of null object

Upon transitioning from Angular 2 RC5 to 2.0 Final, I've encountered some errors while running my tests. It's puzzling me as to what could be causing this issue. TypeError: Cannot read property 'injector' of null at TestBed._create ...

Having trouble grasping this concept in Typescript? Simply use `{onNext}` to call `this._subscribe` method

After reading an article about observables, I came across some code that puzzled me. I am struggling to comprehend the following lines -> return this._subscribe({ onNext: onNext, onError: onError || (() => {}), ...

An issue occurred in the modal window following the relocation of project files

I encountered an issue with the modal in my Nativescript project after rearranging a few project files, including the modal. I updated the imports and deleted any compiled JavaScript files to ensure that my project could recompile correctly. Although I&ap ...

TypeScript generic type and potential absence of a value

Recently, I've been delving into Facebook's immutable library and exploring their TypeScript bindings. Consider this snippet of code: const list: User[] = ...; list.map(user => ...) The lambda parameter user correctly has the type of User. ...

Decide whether to fulfill or deny a Promise at a later time in

When working on an Angular2/TypeScript project, a dialog is shown and the system returns a Promise object to the caller. This Promise will be resolved after the user closes the dialog. The interface of the Promise class does not include methods like resol ...

How can I utilize Javascript XMLHttpRequest to redirect to a different component in Angular 2?

I am attempting to perform a POST request using XMLHttpRequest and I would like to redirect to another component if the xhr request is successful. Here is the code snippet: import {Component, Inject, Injectable, OnInit} from 'angular2/core' imp ...

Karma Unit test: Issue with accessing the 'length' property of an undefined value has been encountered

While running karma unit tests, I encountered a similar issue and here is what I found: One of my unit tests was writing data to a json file, resulting in the following error: ERROR in TypeError: Cannot read property 'length' of undefined a ...

Utilizing Angular Forms for dynamic string validation with the *ngIf directive

I have a challenge where I need to hide forms in a list if they are empty. These forms contain string values. I attempted to use *ngIf but unfortunately, it did not work as expected and empty fields are still visible in the list. How can I address this iss ...

Generate a table in MongoDB using NestJs without the need to create a new collection

I am facing a challenge with my app where I need to create an order with multiple attributes, one of which is an array of ordered products. Each object in the orderedProduct array must include the productId and the amount. However, I do not want to create ...

Steps for connecting an HTML file to tabs in Angular 2

Currently, I have set up files like 'auth.ts' and 'auth.html', along with a main page (menu.html and menu.ts) where tabs are displayed. My intention is to associate the auth.html file with one of the tabs for user login functionality, a ...

Tips for adjusting the dimensions of a map within the app.component.html

Within the code snippet below, my aim is to adjust the width and height of the map using the style tag shown here: <style> #map3 .map { width: 100%; height:90px; } </style> Despite trying various values for width an ...

The object assigned in the Facebook login method cannot be utilized

I'm working on integrating Facebook login with Angular 2. Here's the button for logging in: <button ion-button (click)="fbLogin()"><ion-icon name="logo-facebook"></ion-icon>Login using Facebook</button> Below is the clic ...

Encountering a bug in Angular 11 while fetching data from the backend to display on the screen - facing an issue with trying to access property 'values' of an undefined variable

I am currently working on retrieving data from the backend/api and attempting to display it using *ngFor. However, I am encountering the following errors: Cannot read property 'values' of undefined Below are the components, service codes, and ...

How can we assign dynamic unique IDs to HTML elements within a for..of loop in TypeScript?

Within my array, I am using a for..of TypeScript loop to dynamically add identical HTML elements. Each element needs to have a unique ID. Is it feasible to achieve this directly within the for..of Typescript loop? The code snippet is as follows: for (le ...

Guide to creating a constants file in Node.js

Currently working on creating a constants file in nodejs, but encountering an issue: ERROR in src/app/esri-map/sti/sti-layers-urls.ts(1,1): error TS2304: Cannot find name 'module'. Here is the content of the constants file (sti-layers-urls.ts): ...

Limit the elements in an array within a specified range of dates

Currently, I am working on implementing a filter functionality for a data array used in a LineChart within my Angular application using TypeScript. The structure of the data array is as follows: var multi = [ { "name": "test1", "series": [ ...

Adding a dynamic click event in HTML using IONIC 4

I've created a function using Regex to detect URL links and replace them with a span tag. The replacement process is working fine, but I'm facing an issue where when I include (click)="myFunction()" in the span, it doesn't recognize the cli ...