Typescript promise reject type

Typescript Promise rejection type

Cause there is no way to set error type in some cases like Promise, or exception throws, we can work with errors in rust-like style:

// Result is the type used for returning and propagating errors. // It is an sum type with the variants, // Ok, representing success and containing a value, and // Err, representing error and containing an error value. export type Ok = < _tag: "Ok"; ok: T >; export type Err = < _tag: "Err"; err: E >; export type Result = Ok | Err; export const Result = Object.freeze(< Ok: (ok: T): Result => (< _tag: "Ok", ok >), Err: (err: E): Result => (< _tag: "Err", err >), >); const start = (): Promise> => < return new Promise((resolve) =>< resolve(someCondition ? Result.Ok("correct!") : Result.Err(-1)); >); >; start().then((r) => < switch (r._tag) < case "Ok": < console.log(`Ok < $>`); break; > case "Err": < console.log(`Err < $>`); break; > > >); 

As explained in this issue, Promise doesn’t have different types for fulfilled and rejected promises. reject accepts any argument that doesn’t affect type of a promise.

Currently Promise cannot be typed any better. This results from the fact that a promise can be rejected by throw ing inside then or catch (this is a preferable way to reject existing promise), and this cannot be handled by typing system; also, TypeScript also doesn’t have exception-specific types except never .

Читайте также:  Только латинские символы java

What @EstusFlask mentioned in his answer is correct.

But I want go one step near to an artificial solution to simulate what we want with TypeScript capabilities.

Sometimes I use this pattern in my codes😉:

interface IMyEx < errorId:number; >class MyEx implements IMyEx < errorId:number; constructor(errorId:number) < this.errorId = errorId; >> // ------------------------------------------------------- var prom = new Promise(function(resolve, reject) < try < if(. ) resolve('Huuuraaa'); else reject(new MyEx(100)); >catch (error) < reject(new MyEx(101)); >>); // ------------------------------------------------------- prom() .then(success => < try < >catch (error) < throw new MyEx(102); >>) .catch(reason=>< const myEx = reason as IMyEx; if (myEx && myEx.errorId) < console.log('known error', myEx) >else < console.log('unknown error', reason) >>) 

The exception is typed any because we cannot guarantee the correct type of the exception at design time, and neither TypeScript nor JavaScript provide the ability to guard exception types at run time. Your best option is to use type guards to provide both a design-time and run-time check in your code.

Источник

How to declare the TypeScript Promise rejection type

Consider a utility function that returns a rejected Promise.

export function rejectWithNumber(n: number): Promisenumber>  return Promise.reject(n); >

This compiles, but the return type declaration isn’t correct.

In Promise , T is the fulfillment type. The rejection type is always any .

So what’s the correct return type declaration for the function?

export function rejectWithNumber(n: number): Promiseany>  return Promise.reject(n); ^^^^^^^^^^^^ >

This is a little confusing, though.

This function doesn’t return a Promise because the rejection type is always any . It returns a Promise because it doesn’t know what the Promise’s fulfilled type is. Only the calling function knows.

It’s not possible to declare the TypeScript Promise rejection type. It’s always any .

Copyright © 2022 Seth M. Livingston
Made with ❤️ using Astro and Style.css.

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promise rejection type. #39680

Promise rejection type. #39680

Awaiting More Feedback This means we’d like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

Search Terms

Suggestion

Add ability to type Promise rejections.

// Current Promise Constructor Implementation: new T>(executor: (resolve: (value?: T | PromiseLikeT>) => void, reject: (reason?: any) => void) => void): PromiseT>; // Proposed Change: new T, E = any>(executor: (resolve: (value?: T | PromiseLikeT>) => void, reject: (reason?: E) => void) => void): PromiseT, E>;

Use Cases

When handling promise rejections, the type any isn’t very useful. I would be useful to have the rejection have an actual type without the need to cast or type guard.

Examples

Promise.rejectnever, string>('hello world') .catch(reason =>  console.error(reason.length); // `reason` is of type string. >);
class MyError extends Error  // . > Promise.rejectnever, MyError>(new MyError(/* . */)) .catch(reason =>  // `reason` is of type MyError. const info = reason.getMoreInfo(); // . >);

Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

The text was updated successfully, but these errors were encountered:

RyanCavanaugh added Awaiting More Feedback This means we’d like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Jul 21, 2020

I don’t feel like they rejection type always has to be of type any / unknown .

It is obviously possible to detect what the rejection type is when Promise.reject is used. The hard bit would be detecting rejections caused by a throw statement inside an async function. But if we approach it from the perspective of a throw statement just being an alternative type of return statement, it seems possible to me (but maybe quite difficult).

I’ve been having a bit of a play with this to see what it would be like add support. This is what I’ve got so far just by playing with type definitions.

p2 // p2 is of type Promise .then((v2) => void cosnole.log(v2)) // v2 is of type number .catch((e2) => void console.error(e2)); // e2 is actually type string | ReferenceError, not string

Why would the type be string | ReferenceError ? Isn’t TypeScript already be reporting ReferenceError when they happen (2304)? (Or is that a strict mode only thing? If so then this proposal could just be for strict mode.)

Yes, TS will report 2304 in this obvious case however emitted JS code will still have a change to receive both string and ReferenceError . Idea is to show that if there is something between resolve and catch — there are no guarantees that code between them wont throw something else (e.g. failed network request, incorrect normalize function etc.)

Looks like string will be only true for case p2.catch(. ) but only if you believe that there are no other errors before resolve / reject (which might not be always true).

Could you give a small example?

If myPromise.then(. ).catch(. ) can’t be handled due to this but myPromise.catch(. ) could be, imo that’s still worth pursuing.

In unsound cases or unknown external code (e.g. computedBoolean ) there is always a chance to have behavior that will throw

declare const computedBoolean: (params: any) => boolean; // but in general case might throw const list = [id: 111>, id: 222>]; function firstThreeIds(data: Arrayid: number>>): number[]  return [ data[0].id, data[1].id, data[2].id // no compile time error, but will throw ]; > const p = new Promisenumber[], string>((resolve, reject) =>  if (computedBoolean(list))  // can throw before resolve resolve(firstThreeIds(list)); // wil throw before resolve > else  reject("foo"); > >); p .catch((e) =>  /* . */>); // actually string | TypeError

So it looks like closest thing e can be typed is E | Error in definition ( string | Error in current example).
And again if computedBoolean won’t throw anything else (not sure which case will be encountered more often).

Источник

Оцените статью