Devendra Verma
Devendra Verma

Reputation: 1015

Remove undefined resolved promise from array of promise in typescript

I am using typescript and I have a scenario where I have an async function which will return me value string or undefined when it will be resolved. Prototype of function look like this :

const someFunction = async(someParam : string) => Promise<string | undefined>

Now I will call this function in another function(say myFunction) for some different values and get the promise.

const myFunction = async(params : string[]) : Promise<string[]> => {
    const results = params.map(async (param) => {
        const value = await someFunction(param);
        return value;
    });
    return Promise.all(results);
};

Here I am getting below error:

Type '(string| undefined)[]' is not assignable to type 'string[]'.
  Type 'string | undefined' is not assignable to type 'string'.
    Type 'undefined' is not assignable to type 'string'.)

I want to remove those undefined values(this thing can be done using filter) but also I don't want to change my return type of myFunction.I want to keep its return type Promise<string[]> instead of Promise<(string | undefined)[]>. Can someone help me how could I do this?

Update :I have removed undefined values like this :

const myFunction = async(params : string[]) : Promise<string[]> => {
    const results = params.map(async (param) => {
        const value = await someFunction(param);
        return value;
    }).filter(value => value!== undefined);
    return Promise.all(results);
};

Now I have removed undefined values. But still I am getting the same error which I was previously getting. Typescript is still asking me to change return type of my function from Promise<string[]> to Promise<(string | undefined)[]>

Upvotes: 0

Views: 2095

Answers (1)

Felix Kling
Felix Kling

Reputation: 816462

As you said, .filter can be used to remove undefined values:

const myFunction = async(params : string[]) : Promise<string[]> => {
    const results = await Promise.all(params.map((param) => someFunction(param)));
    return results.filter((r): r is string => r !== undefined);
};

However, we need to help Typescript a little bit to understand that the callback filters out undefined values, which is what the r is string (a type predicate) is for.

Upvotes: 6

Related Questions