Creating a versatile function that can function with or without promises is a valuable skill to have

I am currently working on developing a versatile sort function that can function with or without promises seamlessly.

The intended structure of the function should look something like this:

function sort<T>(list: T[], fn: (item: T) => string | number): T[];
function sort<T>(list: Promise<T[]>, fn: (item: T) => string | number): Promise<T[]>;

The objective is to be able to use the function regardless of whether the input list is a promise or not, while ensuring that the return type matches the input type.

I have implemented similar constructions for other data types, such as a map function that works for both arrays and objects. However, dealing with promises adds an extra layer of complexity, as marking the method as async would require it to always return a promise.

Is there a way to achieve this? Can this be done?

Answer №1

After some trial and error, I was able to figure out the solution on my own. The key is to utilize the ability to chain promises:

function sort<T>(list: T[], fn: (item: T) => string | number): T[];
function sort<T>(list: Promise<T[]>, fn: (item: T) => string | number): Promise<T[]>;
function sort<T>(list: Promise<T[]> | T[], fn: (item: T) => string | number): Promise<T[]> | T[] {
  const doPlainArraySort = (items: T[]): T[] => { /* Implement your sorting algorithm here */ };

  if (list instanceof Promise) {
    return list.then(doPlainArraySort);
  }

  return doPlainArraySort(list);
}

The only drawback of this approach is that determining whether an object is a promise may not be straightforward, but aside from that, it functions as intended!

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

Typescript Angular2 filtering tutorial

In Angular 2 using TypeScript, the goal is to search for matching values from an array within an object array. The intention is to filter out any objects where the 'extraService' property contains any of the values from the 'array_values&apo ...

Is there a way to add an event listener to dynamically generated HTML using the v-html directive?

I have a string variable named log.htmlContent that contains some HTML content. This variable is passed into a div to be displayed using v-html. The particular div will only be displayed if log.htmlContent includes an img tag (http: will only be present in ...

The synergy between ternary operators and Vue filters

Recently, I came across a peculiar issue while working with Vue. Take a look at the code snippet from vue.html: <label :text= "$props.information ? (($props.information.primary || $props.information.secondary) | myFilter) : `No info`"> </lab ...

Angular selects the initial three arrays out of an array

In my code, I have a collection of arrays that are nested within another array. My task is to extract the first three arrays from this collection. For instance, consider the following example: [{[1]},{[2]},{[3]},{[4]}] I apologize for not presenting a p ...

Typescript: Understanding the question mark usage on arrays

In this example, I have the basic structure of my code: let myArray: (Array<any> | null); if (cnd) { myArray = []; myArray?.push(elt); // Curious about this line myArray[0].key = value; // Questioning this line } else { myArray = null; } Wh ...

Steps for modifying the look of a button to display an arrow upon being clicked with CSS

Looking to enhance the visual appearance of a button by having an arrow emerge from it upon clicking, all done through CSS. Currently developing a React application utilizing TypeScript. Upon clicking the next button, the arrow should transition from the ...

What steps do I need to take to create a fresh interface in useState with the help of Typescript

I'm attempting to replicate an input by utilizing useState with an interface. Each time I click on the + button, the interface should be duplicated in the state, thereby duplicating my input. Here is the code I am working on: interface newInputsInter ...

Modifying the value upon saving in Adonis JS model

Using Adonis js I am facing an issue when trying to convert an ISO string to Datetime while saving data (the opposite of serializing DateTime fields to ISO string). I cannot find a way to do this in the model, like I would with a mutator in Laravel. Whene ...

Arranging Pipe Methods in RxJS/Observable for Optimal Functionality

In the class Some, there is a method called run that returns an Observable and contains a pipe within itself. Another pipe is used when executing the run method. import { of } from 'rxjs'; import { map, tap, delay } from 'rxjs/operators&ap ...

Is it possible to define a namespaced external module in TypeScript?

Currently, I am dealing with some legacy js modules that are either namespaced on window or define'd if the page is using AMD. Here's an example: // foo/bar.js (function (root, factory) { if (typeof define === "function" && define.am ...

If the input is unmounted in react-hook-form, the values from the first form may disappear

My form is divided into two parts: the first part collects firstName, lastName, and profilePhoto, while the second part collects email, password, confirmPassword, etc. However, when the user fills out the first part of the form and clicks "next", the val ...

Issues may arise in Typescript when trying to return an array of data from a redux createAsyncThunk function

Below is the code I am using to retrieve a list of users: export const fetchUserById = createAsyncThunk( "users/fetchById", async (_, { rejectWithValue, fulfillWithValue }) => { try { const response = await fetch(`https://reqres. ...

How can I use a string variable in Angular 2 to create a dynamic template URL

@Component({ selector: 'bancaComponent', templateUrl: '{{str}}' }) export class BancaComponent implements OnInit { str: String; constructor(private http: Http) { } ngOnInit(): void { this.str = "./file.component.html"; } An ...

Ways to verify the presence of isBrowser in Angular 4

Previously, isBrowser from Angular Universal could be used to determine if your page was being rendered in a browser (allowing for usage of features like localStorage) or if it was being pre-rendered on the server side. However, it appears that angular2-u ...

What is the process for comparing two objects in TypeScript?

There is a unique class named tax. export class tax { private _id: string; private _name: string; private _percentage: number; constructor(id: string = "", taxName: string = "", percentage: number = 0) { thi ...

Break down and extract elements using typedEvent in TypeScript

Within the external library, there is the following structure: export interface Event extends Log { args?: Result; } export interface TypedEvent<EventArgs extends Result> extends Event { args: EventArgs; } export type InstallationPreparedEven ...

Angular form field not connected to data source

Here is a form I'm working with: <form #appForm> <div...> <select id="transversal" name="transversal" [ngModel]="app.transversal" type="select" required #transversal="ngModel"> < ...

How can JSON be best connected in Angular for optimal performance?

My JSON structure is as follows: { items:[], errors:[], foundItems:9 } One part of my program requires access to "items", while another part needs access to "errors." To resolve this issue, I decided to create a new interface and a new class to hand ...

Guide to extracting the JSON array from a JSON object with Angular

In my angular application, I have made a call to the API and retrieved a JSON object in the console. However, within this JSON object, there are both strings and arrays. My task now is to extract and parse the array from the object in the console. The JSO ...

Using Typescript: invoking static functions within a constructor

This is an illustration of my class containing the relevant methods. class Example { constructor(info) { // calling validateInfo(info) } static validateInfo(info):void { // validation of info } I aim to invoke validateInfo ...