How can we eliminate the need for specifying the order of generic arguments in TypeScript?

In the development of my middleware engine, I have incorporated various generic arguments that are specific to the particular implementation in use.

export type Middleware<

  Store = never,
  Args = unknown,
  Response = unknown

> = (

  context: {
    endpoint: string
    args: Args
    locals: {
      store?: Store,
      [key: string]: unknown
    }
  }

) => Promise<Response|void>|Response|void

The range of generic arguments is continuously expanding as I enhance the Middleware with more features. At times, a store may not be present while other arguments are required. While defaults and parameter order can be relied upon, it becomes cumbersome for developers when listing arguments in the correct sequence and specifying unknown or never for those preceding others that need definition.

I am exploring alternative methods of supplying arguments to generics without depending on a fixed order, allowing for any number of relevant generic arguments while defaulting others to a predefined value in the most general scenario. Could a mapping approach potentially offer a solution?

Answer №1

If you need to work with a single type that has certain properties, you can define it like this:

type Retrieve<T, K extends PropertyKey, TDefault> = 
    [T] extends [Record<K, infer U>] ? U : TDefault

export type MiddleHandler<T extends {
  Data?: any,
  Inputs?: any,
  Result?: any
}> = MiddlewareProcess<Retrieve<T, 'Data', never>, Retrieve<T, 'Inputs', unknown>, Retrieve<T, 'Result', unknown>>
export type MiddlewareProcess<

  Data = never,
  Inputs = unknown,
  Result = unknown

> = (

  info: {
    destination: string,
    inputs: Inputs,
    location: {
      data: Data,
      [id: string]: unknown
    }
  }

) => Promise<Result|void> | Result | void

Check out the code in TypeScript Playground

It may not be an exact match, but it could serve your needs adequately.

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

Learning to implement $first in an Angular ng-repeat to dynamically add a new table row

I am currently facing an issue with displaying a Google map for addresses in my Angular application. The problem seems to be related to the asynchronous nature of HTML and JS, but I am struggling to find a solution. The issue is that even though the map vi ...

ReactJS requires HTTP server to transpile babel code before running

I am a beginner when it comes to working with reactjs and I am currently in the process of setting up babel to execute babel code without having to serve HTTP files. Following the instructions on the Package Manager, I have successfully installed it along ...

retrieve the position of a descendant element in relation to its ancestor element

I'm encountering a challenge while attempting to solve this issue. I have elements representing a child, parent, and grandparent. My goal is to determine the offset position of the child (positioned absolutely) in relation to the grandparent. However, ...

Show only the populated fields in a user profile with ReactJS

Purpose Showcasing only completed fields. Context In my app, users fill out an application with fields like "early reg fee, early reg date, regular reg fee, regular reg date". After completing all the information and clicking "view profile", they should ...

Is it possible to disregard any spaces within the content of an <option> element?

In my current project, I am facing an issue where a Django server is sending JSON data to a template with Vue.js running on it. The problem arises from the fact that some values in the JSON data have trailing spaces, causing complications. I am looking for ...

Is there a way to retrieve the Marker that is being dragged when the event handler has already been bound?

How can I identify the Marker that is being dragged when the handler is a bound function? Take a look at this snippet from my react component: constructor() { this.handleMarkerMove = this.handleMarkerMove.bind(this); } createMarker() { const marker ...

Div Randomly Transforms Its Vertical Position

After successfully creating a VS Code Extension for code completion, I decided to develop a website as a landing page where users can sign up and customize their extension settings. The editor I built pops up first on the page seemed to be working fine in ...

Dealing with numerous promises simultaneously using AngularJS Factory

I have created a code that makes multiple $http calls recursively and saves all the promises it returns in an array. Then, I resolve all of them and save the responses in another array. Now, my question is: How can I efficiently return this final array to ...

The HTML div captured with html2canvas is incomplete

I am currently developing a meme editor website utilizing the html2canvas library available at Below is the HTML code for the div I aim to capture: <div class="container"> <div id="theUserMeme"> <div class=& ...

Tips for integrating Apache Solr with Cassandra without using DataStax Enterprise (DSE)

Embarking on a new project, I find myself utilizing Cassandra as the chosen DBMS, with Apache Solr serving as the search engine and Node.js powering the server scripting language. While I am well-versed in Node.js, Cassandra and Solr are unfamiliar territ ...

`How can I customize the appearance of individual selected <v-list-item> across various sub-groups?`

As a newcomer to Vuetify and Vue in general, I am struggling to solve a specific issue. I need to create multiple sub-groups where only one option can be selected within each "parent" list. Consider an array of cats: options:["Crookshanks", "Garfield", " ...

Modify a single field in user information using MySQL and NodeJS

I am currently working on developing a traditional CRUD (create, read, update, delete) API using NodeJS/Express and MySQL. One of the routes I have created is responsible for updating user information, which is functioning correctly. The issue: When I d ...

The Jquery code encountered an issue where it was unable to access the property 'length' of an undefined

My goal is to submit a form using jQuery and AJAX, which includes file upload functionality. The challenge I'm facing is that the forms are dynamically created, so I need to identify which form was clicked and retrieve its input values. $(document).r ...

Exploring the isolated scopes of AngularJS directives

Exploring directives in AngularJS led me to this interesting code snippet: var app = angular.module('app', []); //custom directive creation app.directive("myDir", function () { return { restrict: "E", scope: { title: '@ ...

Incorporating an HTTP header into d3.json using queue.js

I know that I can include a header in a D3 JSON request by using the following code: d3.json("http://localhost:8080/data") .header("Application-ID", "1") However, I'm uncertain about how to add this header when utilizing queue's defer method. ...

What could be causing the resolve method to not send any data back to the controller?

While following a tutorial on YouTube, I encountered an issue with incorporating the resolve method getposts into the contactController. Despite my efforts, no value is being returned. I've spent hours searching for answers on Stack Overflow to no av ...

What is the best approach for manipulating live data in localStorage using ReactJS?

I am working on creating a page that dynamically renders data from localStorage in real-time. My goal is to have the UI update instantly when I delete data from localStorage. Currently, my code does not reflect changes in real-time; I have to manually rel ...

What is a practice for utilizing navCtrl.push() with a variable storing a class name?

Currently, I am utilizing Visual Studio Code for Ionic 3 development with AngularJS/Typescript. In my code, I am using this.navCtrl.push() to navigate to different pages within the application. Specifically, I have two classes/pages named "level1" and "lev ...

Add United States as an additional attribute to the countries retrieved from the API

I am working with an API that provides data in a specific format: [ { "id": 12, "acf": { "address": { "city": "Bandar Penawar", "state": "Johor", "country ...

Switching the default browser for npm live-server

When I use the npm live-server package to preview my website as it changes, it keeps opening in Edge even though Chrome is set as my default browser on my system. I attempted to use the command suggested on the npm website: live-server --browser=chrome H ...