What is the best way to specify parameter names and types for a TypeScript function that can take either one or two arguments?

Looking to create a function with two different calling options:

function visit(url: string, options: Partial<VisitOptions>): void
function visit(options: Partial<VisitOptions> & {url:string}): void

I'm exploring the most effective way to implement this.

This is what my current code looks like:

type VisitOptions = {
  timeout: number
}

function visit(url: string, options: Partial<VisitOptions>): void;
function visit(options: Partial<VisitOptions> & { url: string }): void;
function visit(...params: any): void {
  let finalOptions: Partial<VisitOptions> & { url: string };
  if (params.length === 1) {
    finalOptions = params[0];
  } else {
    const [url, options] = params;
    finalOptions = {
      url,
      ...options
    }
  }
  console.log(finalOptions);
  // ... more
}

In the actual implementation of the function, you'll find:

function visit(...params: any): void

I am using ...params: any as a parameter, which works but sacrifices type safety within the function body.

Any suggestions for a better approach?

Answer №1

To simplify this scenario, one can utilize a combination of tuples within a union. By leveraging the length attribute for discrimination between tuples, it ensures all types align as anticipated while maintaining type safety:

type PurchaseDetails = {
  price: number
}

function purchase(item: string, details: Partial<PurchaseDetails>): void;
function purchase(details: Partial<PurchaseDetails> & { item: string }): void;
function purchase(...params: [Partial<PurchaseDetails> & { item: string }] | [string, Partial<PurchaseDetails>]): void {
  let finalDetails: Partial<PurchaseDetails> & { item: string };
  if (params.length === 1) {
    finalDetails = params[0];
  } else {
    const [item, details] = params;
    finalDetails = {
      item,
      ...details
    }
  }
  console.log(finalDetails);
  // ... additional logic
}

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

Tips for Disabling ML5 Posenet

Looking to halt Posenet after completing app task private sketch(p: any) { p.setup = () => { this.poseNet = ml5.poseNet(p.createCapture(p.VIDEO), { outputStride: 8 }); this.poseNet.on(&apos ...

Warning: An alert has been triggered while generating files using create-react-app

npm WARN <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e896999d9c81849ba8dbccd1ded8d4cfdcd0c59bc6cbca">[email protected]</a> requires a peer of typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= ...

Using TypeScript to incorporate JS web assembly into your project

I have been attempting to incorporate wasm-clingo into my TypeScript React project. I tried creating my own .d.ts file for the project: // wasm-clingo.d.ts declare module 'wasm-clingo' { export const Module: any; } and importing it like this: ...

Enforcing object keys in Typescript based on object values

I'm looking to design a structure where the keys of an object are based on values from other parts of the object. For example: type AreaChartData = { xAxis: string; yAxis: string; data: { [Key in AreaChartData['xAxis'] | AreaChart ...

Issue with Angular2/4 Module: Unable to locate 'three' in the application directory

As a newcomer to Angular and TypeScript, I am encountering difficulties when trying to import the @types/three npm package. I have created a new Angular project and attempted to use the three package, but I keep receiving the following error: Module not f ...

Eliminate duplicate dropdown options in Angular 2 using a filter function

Is there a way to filter reporting results in an Angular 2 dropdown list? I am currently attempting to do so within the *ngFor template but haven't had any success. I will also try using a custom pipe. The data is coming from a JSON array. Specificall ...

FilterService of PrimeNg

Looking for assistance with customizing a property of the p-columnFilter component. I have managed to modify the filter modes and customize the names, but I am having trouble with the no-filter option. Has anyone found a solution for this? this.matchMo ...

Unveiling the mysteries of abstract classes in TypeScript

I have a collection of different animal classes, all derived from a common abstract base class. To illustrate: abstract class Animal { abstract speak(): string; } class Dog extends Animal { speak(): string { return "woof... sigh" } } ...

typescript optimizing initial load time

When importing the npm package typescript, it typically takes around 0.3 seconds. Is this considered an acceptable load time? Are there any steps that can be taken to optimize performance? The code snippet in index.js demonstrates the process: import &apo ...

Using TypeScript to assign string array values to object properties

I am working with a string array: values: string['myName', 'myLastname', 'myAge'] and my goal is to assign each value to a property of an object like this: myModel={name:'', lastname:'', age:''} o ...

Having trouble utilizing the Visual Studio Code debugger in an Express.js project that uses TypeScript

My package.json file is shown below: ` { "name": "crm-backend", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev" ...

How to generate a SHA256 hash of the body and encode it in base64 using Python compared to

I'm aiming to hash the body using SHA256 and then encode it with base64. I'm in the process of converting my code from Python to TypeScript. From what I gathered via a Google search, it seems like crypto can be utilized instead of hashlib and ba ...

Why does the custom method only trigger once with the addEventListener?

I am attempting to connect the "oninput" event of an input range element to a custom method defined in a corresponding typescript file. Here is the HTML element: <input type="range" id='motivation-grade' value="3" min="1" max="5"> This i ...

how to retain the state value as a number and enable decimal input in a TextField component in React

Currently working on a project using React, Material UI, and TypeScript. I need to enable decimal values in a TextField while ensuring that my state value remains a number type instead of a string. export default function BasicTextFields() { const [value ...

Wait for the product details to be fetched before returning the products with a Firestore promise

Although I know similar questions have been asked numerous times before, I am struggling with something that seems quite straightforward to me. We have two tables - one called "order_lines" and the other called "order_lines_meta". My goal is to query the " ...

Is it considered appropriate to return null in a didReceiveResponse callback function?

In my implementation, I have a callback called didReceiveResponse within a class that extends RESTDataSource. In this method, I return null when the response status is 404. However, due to the typing definition of RESTDataSource.didReceiveResponse, it seem ...

Exploring Angular Testing with SpyOn

Apologies for my inexperience with Angular, but I am struggling with using spyOn in a unit test. In my unit test, there is a method on the component that calls service1, which in turn calls another service2. However, when I try to spyOn service1 in order ...

Determination of the input parameters

Currently, I am developing an Angular application that includes a matInput field for user input. The issue I am encountering is that when the user enters a positive or negative value in the field (e.g. +5 or -5), the final output does not reflect the inten ...

javascript identify dissimilarities within arrays

Working on an Angular 2 application and attempting to identify the difference between two arrays (last seven days and missing dates within the last seven days). Everything works fine when initializing the array through a string, like in example code 1. How ...

Utilize various interfaces for a single object

I'm working on a Typescript project where I need to pass the same object between multiple functions with different interfaces. These are the interfaces: export interface TestModel { fileName:string, year:number, country:string } export interfac ...