Using Typescript to overload functions with varying first parameters

I am facing a scenario where I have a parent class that requires a method implementation with either one or two parameters depending on the child class.

class MyClass { 
    update(obj: HashMap);
    update(id: ID, obj: HashMap);
    update(objOrId: HashMap | ID, obj?: HashMap) {
      console.log('I need to use only the first parameter here');
    }
}

class SubClass extends MyClass {
    update(id: ID, obj: HashMap) {
      console.log('Here I need to utilize both parameters');
    }
}

The issue arises when the SubClass raises an error indicating that the update signature does not match the base class. How can this situation be resolved?

Answer №1

Upon execution, an error will be generated with the following message:

The property 'update' within the type 'SubClass' cannot be assigned to the same property in the base type 'MyClass'.

The type

'(id: ID, obj: HashMap) => void'
is not compatible with the type
'{ (obj: HashMap): any; (id: ID, obj: HashMap): any; }'
.

The reason behind this error lies in the requirement that when overriding a method, it must possess the exact identical type as the original method. As the method in `MyClass` is of an overloaded type with two alternatives, while the overridden method only has one.

Hence, it is imperative to explicitly specify the exact overloads even if they are not strictly needed in the subtype:

class SubClass extends MyClass {
    update(obj: HashMap);
    update(id: ID, obj: HashMap);
    update(objOrId: HashMap | ID, obj?: HashMap) {
      console.log('here I want to use both params');
    }
}

Keep in mind that TypeScript will solely emit the ultimate function definition, without any runtime validation for the parameter types. Therefore, you still need to handle scenarios where only a `HashMap` may be passed to your instance of `SubClass`. This consideration is especially crucial in light of the Liskov substitution principle, which dictates that any instance of `SubClass` should be usable as an instance of `MyClass`; hence passing just a `HashMap` is perfectly acceptable.

Example on TypeScript playground

Answer №2

To ensure compatibility, it is essential to include the public overload signatures in your class. The visibility of the implementation signature is limited, and only the public signatures are checked for compatibility. If these signatures are missing, an error will be triggered by the compiler:

class CustomClass extends BaseClass {
    update(obj: Record<string, any>): void;
    update(id: number, obj: Record<string, any>): void;
    update(objOrId: Record<string, any>, obj?: Record<string, any>): void{
    console.log('Here I intend to utilize both parameters');
    }
}

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

How can I create an Array of objects that implement an interface? Here's an example: myData: Array<myInterface> = []; However, I encountered an issue where the error message "Property 'xxxxxx' does not exist on type 'myInterface[]'" appears

Currently, I am in the process of defining an interface for an array of objects. My goal is to set the initial value within the component as an empty array. Within a file, I have created the following interface: export interface myInterface{ "pictur ...

Create a collection of values and assign it to a form control in Ionic 2

How can I set default values for ion-select with multiple choices using a reactive form in Angular? FormA:FormGroup; this.FormA = this.formBuilder.group({ toppings:['',validators.required] }); <form [formGroup]="FormA"> <i ...

The current state of this scenario is not clearly defined within the parent class

Here is the scenario that caught my attention: abstract class Base { public _obj = { name: 'Test' } print1() { console.log(this._obj) } print2() { console.log(this) } } class Child extends Base { print2( ...

The expected property 'label' is not found in the object type '{ handleClick: () => void; }', but it is required in the object type '{ handleClick: () => void; label: string; }'

I'm encountering difficulties when describing the types of my props. The issue arises with the following code: <PostButton handleClick={props.upvote}/> <PostButton2 handleClick={props.downvote}/> An error message is displayed: Pro ...

Accessing files from various directories within my project

I'm working on a project with 2 sources and I need to import a file from MyProject into nest-project-payment. Can you please guide me on how to do this? Here is the current file structure of my project: https://i.stack.imgur.com/KGKnp.png I attempt ...

Why are the class variables in my Angular service not being stored properly in the injected class?

When I console.log ("My ID is:") in the constructor, it prints out the correct ID generated by the server. However, in getServerNotificationToken() function, this.userID is returned as 'undefined' to the server and also prints as such. I am puzz ...

Implementing query parameters in a Deno controller

I developed a couple of APIs for a Deno Proof of Concept. This is the route implementation: const router = new Router() router.get('/posts', getPosts) .get('/posts/:id', getPostsById) In the second route, I successfully retriev ...

When debugging in Visual Studio 2013, Typescript variables/fields consistently show up as undefined

What is the reason behind the properties/field variables in Typescript being consistently undefined during debugging in Visual Studio 2013? ...

Creating a TypeScript library with Webpack without bundling may seem like a daunting task, but

Currently, I am developing a React component package using Typescript and NPM. During my research, I discovered that generating individual .js and .d.ts files is more beneficial than bundling them into one bundle.js file. However, I am facing difficulty in ...

Exploring Typescript for Efficient Data Fetching

My main objective is to develop an application that can retrieve relevant data from a mySQL database, parse it properly, and display it on the page. To achieve this, I am leveraging Typescript and React. Here is a breakdown of the issue with the code: I h ...

Is the Inline Partial<T> object still throwing errors about a missing field?

I recently updated to TypeScript version ~3.1.6 and defined an interface called Shop as follows: export interface Shop { readonly displayName: string; name: string; city: string; } In this interface, the property displayName is set by the backend a ...

The button event listener in React fails to trigger without a page refresh

Within my index.html file, I have included the following code snippet: <head> ... <script type="text/javascript" src="https://mysrc.com/something.js&collectorId=f8n0soi9" </script> <script ...

When utilizing ng2-bootstrap, there is no directive that is defined with the "exportAs" attribute set to "bs-modal"

I found a tutorial that I am trying to emulate from this website However, when I insert the template into my HTML file <div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}" tabindex="-1" role="dialog" ...

Sharing parameters between pages in Angular IonicPassing parameters between pages within an Angular Ionic application

Is there a way to pass parameters from the signup page to the signupotp page successfully? I am facing an issue where the OTP on the signupotp page is not being recognized because the parameters (email and mobile) are not getting passed properly. In my bac ...

Custom CSS identifier for interactive MuiButton text element

I've been searching for a CSS selector to target this dynamic date element, which is identified as MuiButton-label. While I can currently locate it using xpath in Playwright code, I'm hoping to find an alternative method using a CSS selector. Tha ...

Error encountered: ⨯ Compilation of TypeScript failed

My current project is utilizing Node.js in conjunction with TypeScript An issue has arisen during compilation within my Node.js application: E:\NodeProjects\esshop-mongodb-nodejs\node_modules\ts-node\src\index.ts:859 ret ...

Determine the data type of the value for the mapped type

Is there a way to access the value of a type like the following: interface ParsedQs { [key: string]: undefined | string | string[] | ParsedQs | ParsedQs[] } I am looking for a method to retrieve the ParsedQsValue type without directly duplicating it from ...

Increasing the token size in the Metaplex Auction House CLI for selling items

Utilizing the Metaplex Auction House CLI (ah-cli) latest version (commit 472973f2437ecd9cd0e730254ecdbd1e8fbbd953 from May 27 12:54:11 2022) has posed a limitation where it only allows the use of --token-size 1 and does not permit the creation of auction s ...

Can someone guide me on incorporating static methods into a Mongoose model using TypeScript for Mongoose version 5.11?

When using Mongoose 5.10, I implemented static methods in my Mongoose models with the following pattern: import { Schema, Document, Model, Connection } from "mongoose"; import { v4 } from "uuid"; export interface IFoo extends Document ...

What is the most effective method for delivering a Promise after an asynchronous request?

Currently, I am working on creating an asynchronous function in TypeScript that utilizes axios to make an HTTP request and then returns a Promise for the requested data. export async function loadSingleArweaveAbstraction(absId : string) : Promise<Abstra ...