Issues with overloading of functions

I am facing an issue with function overloading in a scenario where a function can either return something or undefined, depending on the input parameter possibly being undefined as well.

Here is an example:

type Point = { x: number; y:number}

function symetry(point : Point) : Point;
function symetry(point : undefined ) : undefined;
function symetry(point : Point | undefined) : Point | undefined {
    if(!point) return undefined;
    return {
        x : -point.x,
        y : -point.y
    }
}



const p1 : Point = symetry({x: 10, y:-4});
const someFunc = (v : number): Point | undefined => {
    if(v%2 === 0) return undefined;
    return { x:v,y:v}
}

const p2 = symetry(someFunc(0));
const p3 = symetry(someFunc(1));

This code will not compile and shows the following error message for both p2 = and p3 = invocations:

No overload matches this call.
  Overload 1 of 2, '(point: Point): Point', gave the following error.
    Argument of type 'Point | undefined' is not assignable to parameter of type 'Point'.
      Type 'undefined' is not assignable to type 'Point'.
  Overload 2 of 2, '(point: undefined): undefined', gave the following error.
    Argument of type 'Point | undefined' is not assignable to parameter of type 'undefined'.
      Type 'Point' is not assignable to type 'undefined'.

How can I resolve this issue?

Link to TypeScript Playground

Answer №1

When a function declaration is overloaded in TypeScript, the signature of the declaration itself is essentially disregarded.

function symetry(point: Point): Point;
function symetry(point: undefined): undefined;
function symetry(point: Point | undefined): Point | undefined { // no longer considered

According to TypeScript, this function can only be invoked in two ways: with a Point and returning a point, or with undefined and returning undefined. There is no call signature that accommodates both Point | undefined.

If you wish to include Point | undefined, you must add it explicitly:

function symetry(point: Point): Point;
function symetry(point: undefined): undefined;
function symetry(point: Point | undefined): Point | undefined; // appropriate
function symetry(point: Point | undefined): Point | undefined {

Ensure that this overload comes last, as overloads are selected sequentially and the first matching overload is utilized. So avoid doing this:

function symetry(point: Point | undefined): Point | undefined; // incorrect
function symetry(point: Point): Point;
function symetry(point: undefined): undefined;
function symetry(point: Point | undefined): Point | undefined {

otherwise, it will always return Point | undefined for all calls:

const p1: Point = symetry({ x: 10, y: -4 });
//    ~~ Type 'Point | undefined' is not assignable to type 'Point'.

Playground (good)

Playground (bad)

Answer №2

Have you attempted the following:

function symmetry(point?: Point | undefined) : Point | undefined {
    if(!point) return undefined;
    return {
        x : -point.x,
        y : -point.y
    }
}

The '?' indicates that the parameter is optional.

Therefore, symetry() function would still work and simply return undefined in your scenario.

I suggest using:

function symmetry(point?: Point) : Point | undefined

Because it defaults to undefined by default.

Your ts-repro

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

Error message in the console when using a single select checkbox in PrimeNG

When I select one checkbox, the others should be automatically unselected. Additionally, clicking on a selected checkbox should also deselect it. Currently, my implementation looks like this: In the HTML page, I am utilizing *ngFor in the following manner ...

Issue with Angular/Jasmine: Undefined property 'pipe' not readable

I have been struggling to resolve a problem with Angular 9, Jasmine, and RxJS without much success. While my unit tests run successfully in Jasmine, there are certain lines of code that do not get executed. Despite scouring multiple posts for assistance, ...

Ways to fake an interface using Jest without needing to instantiate it

While Kotlin supports this, I haven't been able to find a way to achieve the same in Jest. My problem arises from having intricate interfaces and arrays of these interfaces where specifying all attribute values is not ideal. Here's an example of ...

Can you explain the meaning of <T = MyType>?

While exploring a TypeScript file, I stumbled upon this interface declaration: interface SelectProps<T = SelectValue> extends AbstractSelectProps { /* ... */ } I've searched through the TypeScript handbook for <T = but couldn't find an ...

What is the proper way to combine two arrays containing objects together?

I am faced with the challenge of merging arrays and objects. Here is an example array I am working with: [ { name: "test", sub: { name: "asdf", sub: {} } }, { name: "models", sub: {} } ] ...

Passing an object from @CanActivate() to a component in Angular 2 leads to Typescript Error

Within Angular 2, I am using a MyObjectComponent to display an array of myObjects. These myObjects are retrieved from a MyObjectService, which is called by @CanActivate. @CanActivate((next: ComponentInstruction, previous: ComponentInstruction) => { ...

What are the reasons behind the unforeseen outcomes when transferring cookie logic into a function?

While working on my express route for login, I decided to use jwt for authentication and moved the logic into a separate domain by placing it in a function and adjusting my code. However, I encountered an issue where the client side code was unable to read ...

having difficulty sending a post request with Angular

Submitting form data via HTTP post will look like this: saveDataFile(mutlidata,id,value): Observable<Response> { var _url = 'http://xxxx.xxx.xxx'; var saveDataURL = _url + '/' + id; var _this = this; ...

Encountering a type error with React Navigation 5 while transitioning between stack screens

I have encountered some TypeScript errors while using react-navigation 5. It seems that I might be making mistakes in how I am typing things or structuring the app, but I'm uncertain about the exact issue. I started off by following these guides from ...

Dealing with Exceptions in NestJS and TypeORM: Troubleshooting "Get Status is not a function"

Currently, I am working on an application utilizing NestJS and TypeORM. My main objective is to handle TypeORM errors by using exception filters. However, I have run into a roadblock as I am facing this particular error: (node:345) UnhandledPromiseReject ...

mongoose memory leak attributed to jest

UPDATED 2020-09-14 I've encountered an issue with a test case I wrote. While the testcase passes, it raises a complaint about improper teardown and an open connection. Can anyone help identify the problem: Approach to Solving the Issue - Memory Leak ...

Ensuring proper object updates with TypeScript

Looking for a way to update the student state accurately? In this scenario, a student comprises objects for user, city, and grades. The challenge lies in ensuring that the parameter data passed into the updateStudent function adheres to strict type require ...

Encountering a discord bot malfunction while on my Ubuntu server

My discord bot runs smoothly on my Windows 10 setup, but when deployed to the server running Ubuntu Server 20, it encounters a specific error. The issue arises when trying to handle incoming chat messages from the server. While I can read and respond to m ...

The current version of Aurelia in Karma does not support the use of Reflect.getOwnMetadata as a function

Since I updated to the most recent version of Aurelia (March update beta.1.1.4), I consistently encounter this error whenever I run karma tests: Error: Reflect.getOwnMetadata is not a function Error loading C:/Software/myproject/test/unit/myclass.spec.ts ...

I am encountering difficulties in accessing my component's property within the corresponding template while working with Angular 5

When I call an HTTP POST method to retrieve table names from the backend, I attempt to display them in the template using ngFor. However, the table names are not appearing on the screen. The tNames property is inaccessible in the template. As a beginner i ...

Angular 5 with Typescript encountered a failure in webpack due to the absence of the property "data" on the Response

I am encountering an issue during webpack compilation. It compiles successfully if I remove .data, but then the page crashes with calls from template->component (which in turn calls a service). Here is the error I am facing: ERROR in src/app/compone ...

Angular 7's StyleUrl that Adapts to Your Needs

Is there a better way to dynamically load styles in Angular 7? I have tried the example below but it's not working in version 7 of Angular. This code worked fine in earlier versions before Angular 7. Can someone offer some help or advice please? Thank ...

Ways to modify the access control to permit origin on a specific API URL in React

https://i.stack.imgur.com/tqQwO.png Is there a way to modify the access control allow origin for a URL API? I keep encountering error 500 whenever I try to load the page. After logging in, I included this code snippet: const options = { header ...

Following the Angular 16 upgrade: Issue NG8001: 'element' is unrecognized as a component:

After running nx migrate to upgrade from angular 15 to angular 16, I encountered errors when trying to run nx s. The errors are as follows: Error: apps/webshop/src/app/app.component.html:1:1 - error NG8001: 'eu-toolbar' is not a known element: I ...

Creating an enum in TypeScript can be accomplished by using the enum

What transformations do enums undergo during runtime in the TypeScript environment? Fruit.ts enum Fruit {APPLE, ORANGE}; main.ts let basket = [Fruit.APPLE, Fruit.ORANGE]; console.log(basket); The resulting main.js file remains identical to the .ts ver ...