Plastic
Plastic

Reputation: 10318

Typescript Generic Promise Return Type

Basically I'm trying to implement a function that always returns a fulfilled promise of the same "type" i pass to the function as a parameter

So if I call with a boolean it returns a fulfilled Promise, if I call with a string parameter it returns a fulfilled Promise and so on..

what I tried so far:

const PromiseOK = <T>(val: T): Promise<T> => {
    return Promise.resolve(val);
};

I don't know if it's the proper way to do it and in any case it breaks if i try to get a Promise< void >

Any suggestion will be appreciated

Upvotes: 10

Views: 11691

Answers (3)

Indigo
Indigo

Reputation: 2997

The OP is looking to match the Type of the parameter and return value.

However, if you are looking for a truly generic promise for which the return type is dynamically set by the caller, use this.

const foo = <T>(bar: Bar): Promise<T> => {
  return new Promise<T>((resolve, reject) => {
    // resolve to anything you want that has type T
    // e.g. API response: T
  });
};

// Usage
foo<YourType>(someValueForBar).then().catch();

Upvotes: 1

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249506

You implementation seems fine, the problem with void is that the parameter is still expected. You could call it with undefined

const PromiseOK = <T>(val: T): Promise<T> => {
    return Promise.resolve(val);
};

PromiseOK<void>(undefined)

A better option might be to use overloads to get special behavior for void:

function PromiseOK(): Promise<void>
function PromiseOK<T>(val: T): Promise<T>
function PromiseOK<T>(val?: T): Promise<T> {
    return Promise.resolve(val);
};

PromiseOK() // Promise<void>
PromiseOK(1) //Promise<number>

It is possible to have overloads with arrow functions, but the syntax is not exactly pretty :

const PromiseOK: {
    (): Promise<void>
    <T>(val: T): Promise<T>
} = <T>(val?: T): Promise<T> => Promise.resolve(val);

PromiseOK() // Promise<void>
PromiseOK(1) //Promise<number>

Upvotes: 12

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37584

It should look like this

function PromiseOK<T>(val: T): Promise<T> {
    return Promise.resolve(val);
};

If you want to keep the fat arrow notation, then

const PromiseOK = <T extends any>(val: T): Promise<T> => {
    return Promise.resolve(val);
};

The notation T extends any also supports void.

Upvotes: 0

Related Questions