J. Hesters
J. Hesters

Reputation: 14768

How to handle branching Promises in TypeScript?

I'm trying to type the following promise in TypeScript:

const getUserById = (id: number) => new Promise((resolve, reject) => id === 1
    ? resolve({ id, displayName: 'Jan' })
    : reject('User not found.')
);

TypeScript infers this as

const getUserById: (id: number) => Promise<Unknown>

I have an interface for the user:

interface User {
  id: number;
  displayName: string;
}

Is there any way to have the function getUserbyId recognize that it can either resolve with a User or reject with a string?

Upvotes: 2

Views: 131

Answers (2)

Xinan
Xinan

Reputation: 3162

To get a deeper understanding, you can have a look the type definition for Promise constructor:

declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;

As you can see it takes only one generic type T, which referring to the resolve value type, and it has nothing to do with reject type (always any).

That's why it can not infer the resolve type to be User | string.

Upvotes: 0

ben
ben

Reputation: 361

If Typescript is having trouble inferring it, you can give arrow functions an explicit return type. Typescript will tell you if the type you give it doesn't match what actually happens, so you don't have the same concerns as casting.

const getUserById = (id: number): Promise<User> => new Promise((resolve, reject) => id === 1
    ? resolve({ id, displayName: 'Jan' })
    : reject('User not found.')
);

Upvotes: 1

Related Questions