how to use all parameters except the first one in TypeScript

Is there a way to reference one function's parameter types in another function, but only use a subset of them without repeating the entire list of parameters?

//params of bar should be same as foo, except p1 should be a different type

function foo(p1: string, p2: number, p3: boolean){
 ...
}

//i'd like to do something like this, though it's obviously not valid syntax
function bar(p1: string[], ...rest: Parameters<typeof foo>.slice(1)){
}

In my actual code, I have more than just 3 parameters and manually specifying them is not ideal. Any suggestions on how to achieve this efficiently?

Answer №1

Exploring TypeScript 4.0 Features

Option 1: Simplified Variadic Tuple Syntax

type DropFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never

function bar(p1: string[], ...rest: DropFirst<Parameters<typeof foo>>) { }
// bar: (p1: string[], p2: number, p3: boolean) => void

A new syntax for inferring tuple elements except the first one has been introduced in TypeScript 4.0. Check out Robby Cornelissen's solution for versions prior to 4.0.

Option 2: Named Tuple Elements

type CommonParams = [p2: number, p3: boolean];

function foo2(p1: string, ...rest: CommonParams){} 
// foo2: (p1: string, p2: number, p3: boolean) => void
function bar2(p1: string[], ...rest: CommonParams) { }
// bar2: (p1: string[], p2: number, p3: boolean) => void

Using named tuples can help retain function parameter names, avoiding data loss during conversions.

Try it Out on TypeScript Playground

Answer №2

If you want to create a new type tuple in TypeScript, you can utilize the utility type called Parameters. From there, you can derive a new type by excluding the initial type:

type NewType<T extends any[]> = 
  ((...input: T) => void) extends ((first: infer First, ...rest: infer Rest) => void) ? Rest : never;

function myFunction(firstArg: string, secondArg: number, thirdArg: boolean) {
}

function finalFunction(firstArg: string[], ...restArgs: NewType<Parameters<typeof myFunction>>) {
}


finalFunction([''], 0, true); // works fine
finalFunction('', 0, true); // shows error
finalFunction([''], true, 0); // also displays an error

To learn more about this concept, refer to this insightful answer.

Answer №3

Utilizing destructured object parameters can streamline your code. When passing an object into a function, you have the flexibility to specify which fields from that object will be used.

You have the option to define the parameter interface type separately (as shown with example below), or you can define it directly within the function call (like in sample below).

This allows both functions to extract only the necessary information from the object containing all the parameters.

type ExampleParameters = { key1: string, key2: number, key3: boolean }
function example({ key1, key2, key3 }: ExampleParameters) {
  console.log("Extracted keys from example:", key1, key2, key3)
}

//Hypothetical scenario utilizing inline definition
function sample({ key1 }: { key1: string }) {
  console.log("Selected key from sample:", key1)
}

const data = { key1: "Value One", key2: 5, key3: true }

example(data)
sample(data)

Answer №4

One approach that could simplify the code is by introducing a shared rest parameter type:

type SharedParams = [number, boolean];

// Define function foo with parameters p1 and a destructured array of shared params

function foo(p1: string, [p2, p3]: SharedParams){
    ...
}

// Attempting to create function bar with an array for p1 and rest parameter using SharedParams

function bar(p1: string[], ...rest: SharedParams){
    ...
}

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

Retrieving specific properties from a JSON object and logging them

I am attempting to access JSON Object properties directly and log them using the following function : loadProcesses(filter?){ this._postService.getAllProcess(filter) .subscribe( res=> { this.processListe = res; // console.log(this.p ...

The requested property map cannot be found within the Array

I am working on a project using redux with react typescript. I have an external JSON file that contains employee data categorized by department id. To properly map the data with types in my application, I have created specific types. Check out this demo o ...

Creating a unique Angular 2 Custom Pipe tutorial

I've come across various instances of NG2 pipes online and decided to create one myself recently: @Pipe({name: 'planDatePipe'}) export class PlanDatePipe implements PipeTransform { transform(value: string): string { return sessionStor ...

What is the most effective method to create a versatile function in Angular that can modify the values of numerous ngModel bindings simultaneously?

After working with Angular for a few weeks, I came across a problem that has me stumped. On a page, I have a list of about 100 button inputs, each representing a different value in my database. I've linked these inputs to models as shown in this snipp ...

What is the best way to reload a React/TypeScript page after submitting a POST request?

I am working on a custom plugin for Backstage that interacts with Argo CD via API calls. To retrieve application information, I make a GET request to the following endpoint: https://argocd.acme.com/api/v1/applications/${app-name} If the synchronizati ...

Unclear on the usage of "this" in arrow functions?

After going through various discussions and articles on this topic, I find myself still perplexed about the meaning of this in arrow functions. I've been encountering run-time errors with a code snippet similar to the following: export class Foo imp ...

IntelliJ IDEA does not support the recognition of HTML tags and directives

I seem to have lost the ability to switch between my HTML and TS files in Intellij IDEA; the tags, directives, and autocompletion in HTML are no longer working. Additionally, I'm receiving some warnings: https://i.stack.imgur.com/QjmNk.png Is there ...

When attempting to utilize the dispatch function in a class-based component, an invalid hook call error may

I am a beginner with react-redux. I currently have this code that uses react, redux, and TypeScript. The code utilizes a class-based component and I am attempting to use dispatch to trigger an action to increment the value of counter. However, I encountere ...

Is it possible to begin the vue root instance by using a .vue class component?

Utilizing vue-class-component allows me to incorporate class syntax and TypeScript type checking within my .vue files. I can easily create .vue files and register them as components using this method, with the exception of the root Vue() instance. This ap ...

Utilizing type guards in prop functions for conditional rendering within React TypeScript adds an extra layer

In my code, I am conditionally rendering a Button. However, I encountered an issue on line 7 where TypeScript is indicating that the first parameter of the exportExcel function may be null even though it should not be, considering the conditional render lo ...

What steps do I need to take in order to set up InfluxDB with Nest

As a beginner in the world of software development, I am eager to expand my knowledge and skills. Has anyone had experience operating influxdb with nestjs? If so, I would greatly appreciate it if you could share your past experiences. Thank you for takin ...

Is there possibly a problem with GridActionsCellItem and its props?

I'm encountering a problem with passing props into the GridActionsCellItem within the '@mui/x-data-grid'; columns; { field: 'actions', type: 'actions', width: 80, getActions: (params: any) =&g ...

Retrieve the raw text from the input field instead of the date object

Below is the HTML code for an input field: <div class="input-group input-group-md"> <input id="date" name="date" [readOnly]="disabled" type="text" placeholder="M0/d0/0000 Hh:m0:s0" [placeholder]="pl ...

"Troubleshooting Angular 2 Directives That Cause Errors

Hey there, I'm currently working on understanding ANGULAR 2 routing, but I've encountered an error that's causing some trouble. Here's the issue I'm facing: app/app.component.ts(7,12): error TS2345: Argument of type '{ s ...

Using a Typescript typeguard to validate function parameters of type any[]

Is it logical to use this type of typeguard check in a function like the following: Foo(value: any[]) { if (value instanceof Array) { Console.log('having an array') } } Given that the parameter is defined as an array o ...

It is possible that req.user may be undefined, especially when using express and passport.js

I am facing an issue with my Node.js TypeScript authentication system that utilizes passport. The problem arises when I attempt to access req.user in a specific route, resulting in the error message: Object is possibly 'undefined'. This behavio ...

Finding the right way to cancel a Firestore stream within a Vue component using the onInvalidate callback

Currently, I am utilizing Vue 3 to develop a Firebase composable that is responsible for subscribing to an onSnapshot() stream. I have been attempting to unsubscribe from this stream by invoking the returned unsubscribe() function within both watchEffect ...

Is there a way to insert data from one table into a MySQL Table in Drizzle and update the entry if it already exists?

My goal is to utilize Drizzle for inserting data into a table and updating it if the key already exists. In MySQL, the code would look like this: INSERT INTO myTable1(field1,field2,field3,field4) SELECT fieldOne,fieldTwo,fieldThree,fieldFour FROM myTable2 ...

Connect an Observable to the template with async binding

I've been attempting to link an Observable to a template variable in Angular using the following code: [class.active]="isBookmarked$ | async" During the ngOnInit function, I initialize the Observable: var promise = this.cacheService.getItem(this.bo ...

node-ts displays an error message stating, "Unable to locate the name '__DEV__' (TS2304)."

I recently inserted __DEBUG__ into a TypeScript file within my NodeJS project. Interestingly, in VSCode, no error is displayed. However, upon running the project, I encounter an immediate error: error TS2304: Cannot find name '__DEBUG__'. I att ...