What is the best way to overload a function based on the shape of the argument object in

If I am looking to verify the length of a string in two different ways (either fixed or within a specific range), I can do so using the following examples:

/* Fixed check */
check('abc', {length: 1}); // false
check('abc', {length: 3}); // true

/* Range check */
check('xyz', {minLength: 5, maxLength: 10}); // false
check('xyz', {minLength: 1, maxLength: 10}); // true
check('xyz', {minLength: 3, maxLength: 3}); // true

To achieve this, I have defined two interfaces initially:

interface StringFixed {
  length: number;
}

interface StringRange {
  minLength: number;
  maxLength: number;
}

Next step is to create the function implementation:

function check(value: string, schema: StringFixed): boolean;
function check(value: string, schema: StringRange): boolean;
function check(value: string, schema: StringFixed | StringRange): boolean {
  if (typeof schema.length !== 'undefined') { // ERROR
    // Implementing fixed length check logic
  } else {
    // Implementing range check logic
  }
}

However, TypeScript raises an error at runtime on the line with 'length' property access:

TS2339: Property 'length' does not exist on type 'StringFix | StringRange'

How can I rectify this issue and successfully execute this code in TypeScript?

Answer №1

Almost there! :-) You're inquiring about the type of a property value that is expected to exist (typeof schema.length). To create a type guard, you should check for the existence of the property like this:

if ("length" in schema) {
    // Correct check
} else {
    // Range check
}

Here is a playground link to see it in action on TypeScript playground.

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

Customize the position values of the Ngx-bootstrap Tooltip manually

I have incorporated ngx-bootstrap into my Angular 4 application. The component I am using is ngx-bootstrap Tooltip: After importing it, I am implementing it in my component's view like this: <button type="button" class="btn btn-primary" ...

Why isn't the background-image displaying with the use of the url() function?

I've been attempting to set an image as the background using background-img:url(imageLing), but it's not working properly. When I inspect the element, it shows me background-image: url(assets/backgrounds/5.jpg);. What could be causing this issue? ...

React - Login page briefly appears while loading

Hello, I have built a React application that consists of a Login page, Loading page, and the main app itself. However, there is a small issue where after a user logs in, instead of smoothly transitioning to the Loading page until the data is loaded, the L ...

Using a React component with Material-UI style classes in TypeScript is not possible

Recently delving into react, I've embarked on a learning project utilizing typescript 3.7.2 alongside material-ui 4.11.0 and react 16.13.1. Initially, I structured my page layouts using functional components, but upon attempting to switch them to clas ...

Learning to retrieve the value from a dynamically generated input tag in a TypeScript file

<div *ngFor="let task of arrayList"> <input id="task.fieldName" *ngIf="task.key === 'Others'" type="text" class="form-control"> </div> When dealing with dynamically created input fields based on a condition, the challenge is ac ...

Switching cell icon when clicked - A step-by-step guide

I have a situation in ag-grid where I need to update the icon of a button in a cell when it is clicked to indicate progress and then revert back to its original state upon completion of the action. Below is the code snippet: my-custom.component.ts < ...

The error message indicated that a Promise<string> was expected, but instead a Promise<string|number> was received

Confusion Over Promise Type Error How did the TypeScript compiler generate the error message displaying Type Promise <string|number> ... in the following scenario? Type 'Promise<string | number>' is not assignable to type 'Prom ...

Inquiry regarding the return value of 'async-lock' in nodejs

I am utilizing the async-lock module in my typescript project to handle concurrency. However, I am encountering difficulties with returning the result within lock.acquire(...) {...}. Any guidance on how to resolve this issue would be greatly appreciated. ...

Displaying all notifications while using parameters in TypeScript

I am trying to display all of my notifications in HTML. The value is returned in res = response.json();, but my website only shows one notification, similar to the example in Let's start with this code: public eventsbyserial(id: string): Observab ...

One approach to enhance a function in Typescript involves encapsulating it within another function, while preserving

What I Desire? I aim to create a function called wrap() that will have the following functionality: const func = (x: string) => 'some string'; interface CustomObject { id: number; title: string; } const wrapped = wrap<CustomObject> ...

NextJS-created calendar does not begin on the correct day

I'm facing an issue with my calendar code where it starts rendering on a Wednesday instead of a Monday. I want to adjust the layout so that it always begins on a Monday by adding some empty boxes at the start of the calendar. Essentially, I need to s ...

Can someone explain how to define "a type of object that must not be empty" in typescript?

I'm working with a function that can operate on any type T, but with the constraint that if T is an object, it cannot potentially be empty. Here's what I've tried: declare function myFunction<T>(param: T extends Record<string, neve ...

In TypeScript, a generic function with an index constraint

Is it possible to define an element that operates in the manner indicated here? function fn<T, U extends keyof T, T[U] extends number>() I am having trouble making the "T[U] extends number" portion function correctly. ...

Tips for retrieving a cropped image with Croppr.js

Currently, I am developing a mobile application using Ionic 3. Within the application, I have integrated the Croppr.js library to enable image cropping before uploading it to the server. However, I am facing an issue where I am unable to retrieve the cropp ...

Determining the best application of guards vs middlewares in NestJs

In my pursuit to develop a NestJs application, I aim to implement a middleware that validates the token in the request object and an authentication guard that verifies the user within the token payload. Separating these components allows for a more organi ...

Developing a TypeScript NodeJS module

I've been working on creating a Node module using TypeScript, and here is my progress so far: MysqlMapper.ts export class MysqlMapper{ private _config: Mysql.IConnectionConfig; private openConnection(): Mysql.IConnection{ ... } ...

What is the method to access the information within the observer?

When I receive the data from the observer in the console, here is what I see: https://i.stack.imgur.com/dVzwu.png However, I am only interested in extracting this specific data from each item on the list: https://i.stack.imgur.com/g8oHL.png To extract ...

Can Autocomplete in Angular4+ support multiple selection options?

I am trying to implement a multi-selection feature on filtered items using an autocomplete function. I found inspiration from this tutorial and attempted the following code: The component : <form class="example-form"> <mat-form-field class=" ...

Mapping Form Fields (with Formik)

Currently, the Formik/Yup validation setup in my form is working perfectly: export default function AddUserPage() { const [firstName, setFirstName] = useState(""); const [email, setEmail] = useState(""); return ( <div> <Formik ...

Seamless animation with Angular 4

I'm working on creating a dynamic Homepage in Angular 4 with various cards such as stats, charts, etc., all enhanced with animations. One interesting feature I've implemented is the ability to toggle chart cards to expand to full screen by clicki ...