Dynamic parameters and custom typed parameters

Is there a more efficient method to manage type parameters mapping in TypeScript?

export function $S(): Parser<[]>
export function $S<A>(fn: Parser<A>): Parser<[A]>
export function $S<A, B>(a: Parser<A>, b: Parser<B>): Parser<[A, B]>
export function $S<A, B, C>(a: Parser<A>, b: Parser<B>, c: Parser<C>): Parser<[A, B, C]>
export function $S<A, B, C, D>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>): Parser<[A, B, C, D]>
export function $S<A, B, C, D, E>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>): Parser<[A, B, C, D, E]>
export function $S<A, B, C, D, E, F>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>): Parser<[A, B, C, D, E, F]>
export function $S<A, B, C, D, E, F, G>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>): Parser<[A, B, C, D, E, F, G]>
export function $S<A, B, C, D, E, F, G, H>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>, h: Parser<H>): Parser<[A, B, C, D, E, F, G, H]>
export function $S<A, B, C, D, E, F, G, H, I>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>, h: Parser<H>, i: Parser<I>): Parser<[A, B, C, D, E, F, G, H, I]>
export function $S<A, B, C, D, E, F, G, H, I, J>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>, h: Parser<H>, i: Parser<I>, j: Parser<J>): Parser<[A, B, C, D, E, F, G, H, I, J]>
export function $S(...terms: Parser<any>[]): Parser<any[]>

// Basic definition of parser
interface ParseState {
  input: string
  pos: number
}

interface ParseResult<T> {
  nextPos: number,
  value: T,
}

interface Parser<T> {
  (state: ParseState): ParseResult<T> | undefined
}

I have created a "sequence" function that accepts multiple arguments and I am exploring if there is an automated way to map each type parameter to the response signature without having to create overloads for different numbers of arguments. It seems like this pattern has been used previously, but it's currently 2022 and I'm curious if there are better alternatives.

Additional context that might be pertinent to this inquiry: Each Parser represents a function that evaluates the current state (input string, current position) and returns a ParseResult if it matches at that position or undefined if it doesn't match. The ParseResult includes a value and the new position to advance the input state.

Answer №1

If you want to implement tuple/array mapping, you can do it like this:

define function $S<T extends any[]>(
  ...terms: { [I in keyof T]: Parser<T[I]> }
): Parser<T>;

Mapping a type over an array/tuple type T involves iterating only through numeric-like index keys when T is generic, resulting in another array/tuple type. In your case, the function accepts any type for the example.

In this scenario, T represents an array/tuple-like type with various type parameters (e.g., [A, B, C] for a three-argument call signature). The mapped type

{ [I in keyof T]: Parser<T[I]> }
creates a tuple type equal in length to T, where each element's type is wrapped in Parser<>. For instance, if T is [string, number, boolean], the mapped type will be
[Parser<string>, Parser<number>, Parser<boolean>]
.

To confirm functionality, let's put this into action:

declare constant x: Parser<string>;
declare constant y: Parser<number>;
declare constant z: Parser<boolean>;
const xyz = $S(x, y, z);
// const xyz: Parser<[string, number, boolean]>

Everything seems to be working perfectly!

Click here for Playground link to view the code

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

Create a TypeScript arrow function and set it as the return value

Looking to create a TypeScript Declaration for ReactMeteorData.jsx, which consists of the following exporting functionality: export default function connect(options) { let expandedOptions = options; if (typeof options === 'function') { e ...

Create a custom button in Material-UI using Styled-components, and integrate it with React

I'm currently working on a project using React, TypeScript, and styled components along with the material-ui library. I have created styled material-ui buttons as shown below: import React from 'react' import styled from 'styled-compone ...

Sort the array based on the enum name rather than its value

Below is an example of an enumeration: export enum Foo { AA = 0, ZZ = 1, AB = 2, ER = 5 } In my case, I want to sort my Bars based on the name of the enum (AA, AB, ER, ZZ), rather than the numerical value (0, 1, 2, 5) that they represent. ...

Working with Array of Objects Within Another Array in Angular 6 Using Typescript

I'm currently working with an array of "food": "food": [ { "id": 11, "name": "Kabeljaufilet", "preis": 3.55, "art": "mit Fisch" }, { "id": 12, "name": "Spaghetti Bolognese", "preis": 3.85, "art": "mit Fleisch" }, { "id": 1 ...

What is the best way to import a TypeScript file in index.js?

I've recently developed an application using the react-express-starter template. I have a "server" directory where the backend is created by nodejs, containing an index.js file: const express = require('express'); const app = express(); c ...

The value returned by UseSelector is not defined

this code snippet is responsible for monitoring the state of a shopping cart that contains various bets placed by the user const { games } = useSelector((state: any) => state.cart) which is then passed to another component like this <AppRecentUserG ...

Enhance Vue TypeScript components with custom component-level properties

In my vue2 project, I am utilizing vue-class-component along with vue-property-decorator. My goal is to implement component-level security validation for each component when it loads. I imagine implementing it with a signature like this: @Component @Secur ...

The function http.get() will not give back an observable object

NOTE: The issue lies in the ionViewDidLoad() function not being executed, as the http.get method does return an observable. I am attempting to receive the observable when making a request to later retrieve its json response. However, I am not encountering ...

Attempting to integrate a TypeScript library with a JavaScript Express application

I have been attempting to integrate a TypeScript library like this into an existing Express Node.js application, but unfortunately it is not working as expected. Upon importing the library functions, I keep encountering errors such as "Cannot read property ...

Next.js is refusing to render an array of HTML elements

Consider this scenario where I have a block of code in TypeScript that attempts to create and display a list of elements. Here is a sample implementation: const MenuList = ():ReactElement => { const router = useRouter(), liElements:any = []; con ...

having trouble integrating and utilizing TypeScript with socket.io

Trying to utilize the npm typescript @types/socket.io definition. To set it up, I followed these steps: npm install --save @types/socket.io npm install --save socket.io After that, my package.json now looks like this: ... "devDependencies": { ...

Troubleshooting Angular 2 Typescript: Component not displaying as expected

I am currently in the process of learning Angular 2. Despite encountering numerous error messages, I have successfully set up the routes and can now display the desired component. My next challenge is to incorporate a navbar component into my homepage comp ...

Is it possible to use static imports with Typescript?

Let's imagine that Object is a module that can be imported and currently we are using Object.getOwnPropertyNames. Is it possible to write the following code instead: import {getOwnPropertyNames} from 'Object'; ...

Error message: "The use of Vue 3 refs in the render function is

I am facing an issue with my Vue component wherein the root element is set as ref="divRef". Strangely, when I try to access divRef.value inside the onMounted function, it returns undefined. Any assistance on this matter would be greatly appreci ...

Errors are encountered when attempting to run the React project command

I attempted to start my React.js project, which utilizes typeScript and webpack. However, I ran into numerous errors when executing the command npm run dev (please refer to the snippet attached below). Here is what I attempted: Removed the node_modules d ...

Guide on implementing a cordova plugin in a TypeScript cordova application

In my Cordova project, which utilizes Angular and Typescript, I am facing issues with implementing the juspay-ec-sdk-plugin for Cordova. I have explored possible solutions on StackOverflow related to integrating Cordova plugin in an Angular 4 Typescript ...

Issue with running gulp ser on first attempt in SPFX

Every time I try running gulp serve, I encounter the following issue: Error: Unable to locate module '@rushstack/module-minifier-plugin' Please assist me with this problem. Thank you! ...

It's possible that the "device.interfaces" variable has not been defined

I am currently working on creating a USB driver in TypeScript using the libusb library to adjust my keyboard lighting. However, I encountered an issue where I received a 'possibly undefined' error when trying to retrieve the interface number. The ...

What is the reason Nav cannot be directly used in the constructor instead of using @ViewChild(Nav) nav: Nav in Ionic?

As a newcomer to Ionic, I am trying to understand the code snippet provided. My confusion lies in the purpose of "NAV" and why it is used in @viewchild(). While I can access the MenuController by using it in the constructor, I am unable to use NAV in the s ...

How to verify the existence of an object property in typescript

I am dealing with a queryParams object that I need to use to query the database based on its properties. However, I am unable to determine which parameters it contains. I attempted to utilize find(queryParameters: object = { limit: 50 }){ if (queryParamete ...