Different types are returned based on the constructor overload in TypeScript

I am trying to create a constructor function that can return different types based on a parameter.

interface B {
    hello(): string;
}

class Foo {  
    constructor(withB: boolean): Foo & B;
    constructor();
    constructor(withB?: boolean) {
        if (withB) {
            Object.assign(this, { hello() {}})
        }
    }
}

const foo1 = new Foo();
const foo3 = new Foo(true);

Unfortunately, the code is not working as expected. Can someone help me troubleshoot this issue?

Answer №1

To create a class with different overloads, you can't define it directly. Instead, define your regular class and rename it to FooImpl. Then declare a constant representing the constructor with the different overloads and assign the FooImpl to it:

interface B {
    hello(): string;
}

class FooImpl { 
    constructor(withB?: boolean) {
        if (withB) {
            Object.assign(this, { hello() {}})
        }
    }
}

const Foo : {
    new(withB: boolean): FooImpl & B;
    new() : FooImpl;
}= FooImpl as any;


const foo1 = new Foo(); // FooImpl
const foo3 = new Foo(true); // FooImpl & B

If your interface only has methods, you may also consider using generics and specifying the this parameter on the interface methods. This will restrict their visibility to specific parameters for the type:

interface B {
    hello(): string;

}

class Foo<T=void> {
    private withB: T;  
    constructor(withB: T);
    constructor();
    constructor(withB?: boolean) {
    }
    hello(this: Foo<boolean>): string {
        return "";
    }
}


const foo1 = new Foo();
foo1.hello() // Invalid
const foo3 = new Foo(true);
foo3.hello() // Valid

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

Change the country name to all lowercase letters

I'm attempting to retrieve the country flag icon of the Open Weather Map API. For example: The JSON response for the country code from the API request is in uppercase. To obtain the correct icon for the country, I need the country code in lowercase. ...

Is it possible to use TypeScript or Angular to disable or remove arrow key navigation from a PrimeNG Table programmatically?

Is there a way to programmatically prevent left and right arrow key navigation in a PrimeNG Table with cell editing, without the need to modify the Table component source code? You can check out an example here: Angular Primeng Tableedit Demo code. I mana ...

Errors in TypeScript type definition IntelliSense

While using Visual Studio 2022, I am encountering numerous IntelliSense errors related to type definitions from the node_modules folder appearing in the error list window. I have already excluded the node_modules folder in my tsconfig.json file like this ...

Blend multiple images using Angular

Is there a way to combine multiple images in Angular? I came across some HTML5 code that seemed like it could do the trick, but unfortunately, I couldn't make it work. <canvas id="canvas"></canvas> <script type="text/javascript"> ...

Issues with the visibility of inlined styles within the Angular component library

After developing a custom library with components for an Angular 4 application, I encountered an issue where the CSS styling from the components was not being applied when using them in an application. Although the functionality worked fine, the visual asp ...

Evaluating solely my DefinitelyTyped undertaking

Lately, I've been lending a hand in shaping the jquery.datatables definition over at DefinitelyTyped. Within the repository, you'll find numerous other definition projects, but it's not rare for one or more of them to stumble when put throug ...

How to access a component attribute in a JavaScript library method in Angular 8

Within my Angular project, I am utilizing Semantic UI with the code snippet below: componentProperty: boolean = false; ngOnInit() { (<any>$('.ui.dropdown')).dropdown(); (<any>$('.ui.input')).popup({ ...

The module './product-list/product-list.component' could not be located

As a beginner in Angular, I decided to incorporate a top-bar component into my project by following the structure outlined in the app directory. However, I encountered some issues as indicated by the error message that kept popping up. Despite importing ...

Challenges encountered when using Tailwindcss and Nextjs with class and variables

Hey there, I'm currently facing a major issue with tailwindcss + nextjs... The problem lies in setting classes using a variable. Although the class is defined in the css, tailwind fails to convert it into a style. This is how I need it to be: https ...

Is there a way to assign values of object properties to the corresponding object in TypeScript?

I'm looking for a solution in TypeScript where I can map values of object keys to the same object, and have IntelliSense work correctly. Here's an example that illustrates what I need: const obj = getByName([ { __name: 'foo', baz: &ap ...

How come the type declaration ( () => string ) suddenly pops up?

I am currently utilizing the jasonwebtoken package and have encountered a new javascript/typescript behavior. interface JwtPayload { [key: string]: any; iss?: string | undefined; sub?: string | undefined; aud?: string | string[] | undefined ...

Angular 6 has numerous modules that have similar names but vary only in their letter casing

After running ng serve, I encountered an error that has me stumped. Everything was working fine with the new service I created until suddenly it all crashed :( I tried troubleshooting everything possible but to no avail. Even Google didn't provide any ...

What is the best way to eliminate tasks from a list in Angular?

I have been working on a scheduler tool that allows me to record the tasks I complete within a specific timeframe. These tasks are displayed in a list similar to a to-do list. One of the challenges I'm facing is removing individual items from the lis ...

Is it possible for decorators to invoke services within an Angular application?

Recently, I've delved into exploring decorators for TypeScript. Angular showcases a wide array of decorators like Components, Injectables, Directives, and more. I find myself frequently repeating a logic block that checks if a user is logged in and au ...

How can I create an interceptor in Angular2 to detect 500 and 404 errors in my app.ts file?

Creating an Angular2 Interceptor for Handling 500 and 404 Errors in app.ts In my app.ts file, I am looking to implement an interceptor that can detect a 500 or 404 error so that I can appropriately redirect to my HTML 404 or HTML 500 pages. Is this funct ...

Guide to updating the canvas in Chart.js based on a user-defined x-axis range

What I currently have: My chart.js canvas displays values on the x-axis ranging from 1 to 9. Users can input a new range to view a different scope, with default limits set at start = 3 and end = 6 in my repository. I already have a function that restrict ...

What is the best way to handle arithmetic operations with multiple input fields in Angular?

In my form, users input number values which I need to send to my ts file for multiplication when a button is clicked. View screenshot example Below are the code snippets: calculate(value0,value1){ this.bindData(value0,value1); } bindData(a,b){ ...

Scoped variable in Typescript producing a generated Javascript file

I'm currently learning TypeScript through an online course, and I've encountered a problem that seems to be related to a VSCode setting. Whenever I compile app.ts, it generates the app.js file, but I immediately encounter a TypeScript error. It& ...

How to use TypeScript to filter arrays with multiple dimensions

I've been attempting to filter an array with multiple filters, but I can't seem to achieve the desired outcome so far. This is my Angular component: list = [ {type: type1, code: code1}, {type: type2, code: code2}] searchElement(code?: string, ...

Navigating Through React and TypeScript: Implementing scrollTop

To control the scrolling behavior of a Div tag, I created a reference called listRef: const listRef = useRef<HTMLDivElement>(null); However, attempting to set the scrollTop using this code: listRef.scrollTop = listRef.current.scrollHeight; leads to ...