What methods can TypeScript use to accommodate this kind of Generic Type?

It appears that there is already an existing GitHub issue related to this topic. You can find it here: ts#1213.

This type of usage resembles a high-order function, and I am unsure if TypeScript supports it.

Although the interface remains the same, there is a need to create both synchronous and asynchronous versions.


interface IO<T> {
  get: () => T<number>;
  set: (v: number) => T<boolean>;
}

type Raw<T> = T;

class SyncO implements IO<Raw> {
  get() {
    return 1;
  }

  set(v) {
    v;
    return true;
  }
}

class AsyncO implements IO<Promise> {
  get() {
    return Promise.resolve(1);
  }

  set(v) {
    v;
    return Promise.resolve(true);
  }
}

Answer №1

It's puzzling why there is a non-generic T implemented in the interface, leading to a syntax error when utilized.

To address this issue and create a unified interface, you can utilize union types with |

type syncOrAsync<T> = T | Promise<T>;

interface IO<T> {
  get: () => syncOrAsync<T>;
  set: (v: number) => syncOrAsync<boolean>;
}

class SyncO implements IO<syncOrAsync<number>> {
  get() {
    return 1;
  }

  set(v: number) {
    return true;
  }
}

class AsyncO implements IO<syncOrAsync<number>> {
  get() {
    return Promise.resolve(1);
  }

  set(v: number) {
    return Promise.resolve(true);
  }
}

Answer №2

While exploring the code of RESTyped, I stumbled upon an interesting solution:

type MaybePromise<T, P extends boolean> =
  P extends true ? Promise<T> : T;

interface IO<P extends boolean> {
  get: () => MaybePromise<number, P>;
  set: (v: number) => MaybePromise<boolean, P>;

  invalidSet: (v: number) => MaybePromise<boolean, P>;
}

class SyncO implements IO<false> {
  get() { return 1; }
  set(v) { return true; }

/* ts error:
(method) SyncO.invalidSet(v: any): Promise<boolean>
Property 'invalidSet' in type 'SyncO' is not assignable to the same property in base type 'IO<false>'.
  Type '(v: any) => Promise<boolean>' is not assignable to type '(v: number) => boolean'.
    Type 'Promise<boolean>' is not assignable to type 'boolean'.ts(2416)
*/
  invalidSet(v) { return Promise.resolve(true); }
}

class AsyncO implements IO<true> {
  get() { return Promise.resolve(1); }
  set(v) { return Promise.resolve(true); }

/* ts error:
(method) AsyncO.invalidSet(v: any): boolean
Property 'invalidSet' in type 'AsyncO' is not assignable to the same property in base type 'IO<true>'.
  Type '(v: any) => boolean' is not assignable to type '(v: number) => Promise<boolean>'.
    Type 'boolean' is not assignable to type 'Promise<boolean>'.ts(2416)
*/
  invalidSet(v) { return true; }
}

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

Tips for updating the display after making an angular $http request using rxjs Observables

I have a project where I am utilizing angular's $http service to fetch data from a remote endpoint. I am keen on incorporating rxjs Observables, hence the call in my service is structured as follows: userInfo() : Rx.Observable<IUserInfo> { ...

Angular: controller's property has not been initialized

My small controller is responsible for binding a model to a UI and managing the UI popup using semantic principles (instructs semantic on when to display/hide the popup). export class MyController implements IController { popup: any | undefined onShow(con ...

Tips for accessing the 'index' variable in *ngFor directive and making modifications (restriction on deleting only one item at a time from a list)

Here is the code snippet I'm working with: HTML: <ion-item-sliding *ngFor="let object of objectList; let idx = index"> <ion-item> <ion-input type="text" text-left [(ngModel)]="objectList[idx].name" placeholder="Nam ...

The error "date.isUtc is not a function" is being thrown by MomentAdapter.js

When setting an initial date value for the MUI DatePicker, I encountered the following error: value.isUTC is not a function ./node_modules/@mui/x-date-pickers/AdapterMoment/AdapterMoment.js/AdapterMoment/this.getTimezone@ The date being passed is: 2024-0 ...

Solve the error "Property 'container' of null is not accessible" in musickit.js while running an Angular application on a server

I am currently developing an application that combines Angular and MusicKit to offer users the ability to listen to music simultaneously. However, I encountered a challenging error when trying to run the application using ng serve --host x.x.x.x instead of ...

Exploring Vue with Typescript - leveraging components without explicit definitions

Has anyone successfully used vue-instant component as a child component before? I'm having trouble adding components without definition. Could it be related to webpack config ignoring node_modules due to lack of type declaration? Here's the code ...

Conceal the Angular Material toolbar (top navigation bar) automatically when scrolling downwards

In my Angular application, the main navigation consists of a standard toolbar positioned at the top of the page. My goal is to have this navigation bar smoothly scroll up with the user as they scroll down, and then reappear when they scroll back up. I at ...

What is the best way to implement a comprehensive switch case in Typescript using string enums that are referencing other string enums?

I am faced with a challenge where I have a subset of values from one enum that I need to switch case across in TypeScript. Here's an example to illustrate my dilemma: const enum Fruit { APPLE = 'Apple', BANANA = 'Banana', ...

How can I utilize the color prop in the theme file to style new variants more comprehensively with MUI theming?

I am working on creating a custom variant for an MUI button where the color specified in the color prop should be applied as both the border and text color. While the MUI documentation offers a suggested approach, it requires addressing each available col ...

Remove the Prisma self-referencing relationship (one-to-many)

I'm working with this particular prisma schema: model Directory { id String @id @default(cuid()) name String? parentDirectoryId String? userId String parentDirectory Directory? @relation("p ...

What is the best way to transmit a JSON object to REST services using Angular?

Whenever I attempt to send the JSON object to REST services, I encounter an error that looks like this: http://localhost:8080/api/v1/cardLimit 400 (Bad Request); JSON Object Example: public class GameLimit implements Serializable { private stati ...

Encountered 'DatePickerProps<unknown>' error while attempting to develop a custom component using Material-UI and react-hook-form

Currently, I'm attempting to create a reusable component using MUI Datepicker and React Hook Form However, the parent component is throwing an error Type '{ control: Control<FieldValues, object>; name: string; }' is missing the follow ...

Guide on defining a data type for the response payload in a Next.js route controller

interface DefaultResponse<T> { success: boolean; message?: string; user?: T; } export async function POST(req: Request) { const body: Pick<User, 'email' | 'password'> = await req.json(); const user = await prisma ...

Looking to seamlessly integrate a CommonJS library into your ES Module project while maintaining TypeScript compatibility?

I am interested in creating a project with Typescript. The project is built on top of the Typescript compiler, so I am utilizing Typescript as a library, which I believe is a CommonJS library. Although the project is designed to run on Node (not in the bro ...

Find any consecutive lowercase or uppercase letter and include one more

I have a task in Javascript that I need help with. The goal is to insert a special character between a lowercase and uppercase letter when they are matched together. For example: myHouse => my_House aRandomString => a_Random_String And so on... T ...

What is the optimal method for navigating through a complex nested object in Angular?

Looking to navigate through a nested object structure called purchase. Within this structure, there is a sub-array named purchaseProducts which contains another sub-array called products along with additional data. What methods do you suggest for efficien ...

Hiding a div after three clicks using HTML

What is the best way to hide a div tag containing an input tag after clicking on the input tag three times using HTML and angular? ...

Sending data to a parent component from a popup window in Angular Material using a button click while the window is still open

How can I retrieve data from an Angular Material Dialog Box and send it to the Parent component? I am able to access data after the dialog box is closed. However, I am wondering if there is a way to retrieve data while the dialog box is still open, especi ...

Encountering an error in a map operation does not hinder the subsequent map operation from being carried out

Within my angular application, I have implemented a Login method that performs the following tasks: login(username, password): Observable<User> { let data = new URLSearchParams(); data.append('username', username); data.append(' ...

The functionality of translations within a TypeScript object is currently malfunctioning

I am facing a perplexing issue with my code. I am utilizing lingui for internationalization in my application. The translations are stored using the `t` macro in a TypeScript object, which can be found here: https://github.com/Flaburgan/disco2very/blob/mas ...