Changing function arguments in TypeScript using the spread operator

Could the Tuple spreading syntax in Typescript be utilized to consolidate these function overloads? The challenge lies in the necessity to refactor the function arguments into new types.

type Type = TString | TNumber
type TString = { tag: 'string' }
type TNumber = { tag: 'number' }

interface Mapping {
  string: string
  number: number
}

type Remap<T extends Type> = Mapping[T['tag']];

// Is it possible to merge these function overloads into one?
function checkFn<R extends Type, A extends Type, B extends Type, C extends Type>(argTypes: [A, B, C], retType: R, fn: (arg0: Remap<A>, arg1: Remap<B>, arg2: Remap<C>) => Remap<R>): void;
function checkFn<R extends Type, A extends Type, B extends Type>(argTypes: [A, B], retType: R, fn: (arg0: Remap<A>, arg1: Remap<B>) => Remap<R>): void;
function checkFn<R extends Type, A extends Type>(argTypes: [A], retType: R, fn: (arg: Remap<A>) => Remap<R>): void;
function checkFn(argTypes: any[], retType: any, fn: any): void {}

const stringType: TString = { tag: 'string' }
const numberType: TNumber = { tag: 'number' }

checkFn([numberType, stringType, numberType], numberType, (arg0, arg1, arg2) => 42)

TS playground

Answer №1

By leveraging the power of Variadic Tuple Types (check out the documentation for a more simplified explanation), it is confirmed that the answer is "affirmative":

type DataType = TString | TNumber
type TString = { tag: 'string' }
type TNumber = { tag: 'number' }

interface DataMapping {
  string: string
  number: number
}

type Reassign<T extends DataType> = DataMapping[T['tag']];

function validateFunction<P extends DataType[], R extends DataType>(
  parameters: [...P],
  returnType: R,
  func: (...args: { [K in keyof P]: Reassign<P[K] & DataType> }) => Reassign<R>
): void {}


const stringDataType: TString = { tag: 'string' }
const numberDataType: TNumber = { tag: 'number' }

validateFunction(
  [numberDataType, stringDataType, numberDataType],
  numberDataType,
  (arg0: number, arg1: string, arg2: number) => 42);

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

What is the best way to convert this into a distinct function using typescript?

Is there a way to create a single method in Protractor or Webdriver API that can get the browser width and height? const getWindowWidth = async () => { const size = await browser.manage().window().getSize(); return size.width; }; I need this metho ...

After integrating React Query into my project, all my content vanishes mysteriously

Currently, I am utilizing TypeScript and React in my project with the goal of fetching data from an API. To achieve this, I decided to incorporate React Query into the mix. import "./App.css"; import Nav from "./components/Navbar"; impo ...

Tips for implementing filters in Angular2 without using the package field in the console

I am currently experiencing an issue with a filter field in my code. The filter works fine when all the package data is present, however, some items do not have a package field. As a result, I need to filter based on the package name but I am encountering ...

Tips for iterating through nested objects with a for loop

Struggling with validations in an Angular 5 application? If you have a form with name, email, gender, and address grouped under city, state, country using FormGroupname, you might find this code snippet helpful: export class RegistrationComponent implemen ...

Tips for separating provider and input components with React Hook Form

Currently, I am working on a project with Next 13.5 using react-hook-form and shadcn-ui. The issue that I have encountered is that creating a form involves too much redundant code. To address this, I abstracted the FormProvider and Input component. The pr ...

Having trouble accessing specific results using Firestore's multiple orderBy (composite index) feature

I am facing an issue with a query that I run on various data types. Recently, one of the collections stopped returning results after I included orderBy clauses. getEntitiesOfType(entityType: EntityType): Observable<StructuralEntity[]> { const col ...

When utilizing await/async in TypeScript with Axios, the return type may be incorrect

UPDATE: After some investigation, it turns out the issue was not related to Axios or TypeScript but rather a strange IDE configuration problem. Starting fresh by recreating the environment and .idea folder solved the issue. While working with Axios in Typ ...

Angular 2 signal sender

I have a specific class definition for my Project: export class Project { $key: string; file: File; name: string; title: string; cat: string; url: string; progress: number; createdAt: Date = new Date(); constructor(file: File) { th ...

Creating an interceptor to customize default repository methods in loopback4

Whenever I attempt to access the default repository code, I need to manipulate certain values before triggering the default crud function in the repository. How can I accomplish this? For example: ... @repository.getter('PersonRepository') priva ...

Is there a way to automatically scroll 50 pixels down the page after pressing a button?

Is there a way to make my page scroll down in Angular when a button is clicked? I attempted to use this code, but it didn't have the desired effect. What is the best method for scrolling the page down by 50px? window.scrollBy(0, 50); ...

Encountered an issue while attempting to authenticate CMS signature using pkijs

I am attempting to validate a CMS signature generated with open ssl using the following command: $ openssl cms -sign -signer domain.pem -inkey domain.key -binary -in README.md -outform der -out signature Below is my code utilizing pkijs: import * as pkij ...

How can I confirm if a class is an instance of a function-defined class?

I have been attempting to export a class that is defined within a function. In my attempts, I decided to declare the class export in the following way: export declare class GameCameraComponent extends GameObject { isMainCamera: boolean; } export abstra ...

Angular error TS2322 arises when attempting to assign a type of 'Observable<{}>' with the share() operator

Currently diving into Angular 5, I've been exploring the Observable/Observer pattern to facilitate event sharing and data changes among subscribers. Below is a snippet of the code in question: ... @Injectable() export class NidoService { ... eve ...

Unable to populate an array with a JSON object using Angular framework

Here is the JSON object I have: Object { JP: "JAPAN", PAK: "PAKISTAN", IND: "INDIA", AUS: "AUSTRALIA" } This JSON data was retrieved as a response from an HTTP GET request using HttpClient in Angular. Now, I want to populate this data into the following ...

Testing the subscribe function in Angular within a returned Promise: A guide

I am facing an issue with a service that returns a Promise. It retrieves data from a JSON file using a subscribe method before resolving the Promise. I am trying to test the result of this Promise based on the parameters I provide, but I am encountering t ...

The term "primordials is not defined" is a common error

Whenever I attempt to run Gulp using the task runner, I am encountering this error message. I suspect it may be due to updating my npm project, but I'm unsure about how to resolve it. Should I try installing a different version of npm? >Failed to r ...

In Typescript, it is possible to provide values other than undefined for a parameter that is

I experimented with the code below in TypeScript Playground with all settings enabled. My expectation was that the TS compiler would only allow the first call() to be valid. However, to my surprise, all four calls were accepted. Upon inspecting the calls, ...

Extending Mongoose's capabilities with header files for the "plugin" feature, utilizing the .methods and .statics methods

My task is to develop Typescript header files for a script that enhances my Mongoose model using the .plugin method. The current signature in the Mongoose header files looks like this: export class Schema { // ... plugin(plugin: (schema: Schema, opt ...

The origin of the Angular img src becomes blurred when invoking a function

I want to dynamically change the image src by calling a function that returns the image path. However, when I attempt to do so using the code below, the image element displays as <img src(unknown)/> component.ts: getMedia(row) { this.sharedData ...

Using private members to create getter and setter in TypeScript

Recently, I developed a unique auto getter and setter in JavaScript which you can view here. However, I am currently unsure of how to implement this functionality in TypeScript. I am interested in creating an Object Oriented version of this feature if it ...