typescript 打字稿承诺拒绝类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50071115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:22:50  来源:igfitidea点击:

Typescript Promise rejection type

javascripttypescriptpromise

提问by Kousha

How do I set the type of the rejection of my promise? Let's say I do:

如何设置拒绝我的承诺的类型?假设我这样做:

const start = (): Promise<string> => {
   return new Promise((resolve, reject) => {
      if (someCondition) {
         resolve('correct!');
      } else {
         reject(-1);
      }
   });
}

Let's say I want to reject with a number. But I cannot set the type; I can pass whatever I want to the rejecthere.

假设我想用一个数字拒绝。但是我不能设置类型;我可以通过任何我想要的东西到reject这里。

Moreover, when using this promise, I want to have compiling error if I use the rejection response type incorrectly.

此外,在使用此承诺时,如果我错误地使用拒绝响应类型,我希望有编译错误。

回答by Estus Flask

As explained in this issue, Promisedoesn't have different types for fulfilled and rejected promises. rejectaccepts anyargumentthat doesn't affect type of a promise.

正如在解释这个问题Promise没有不同类型的满足,拒绝承诺。reject接受any不影响承诺类型的参数

Currently Promisecannot be typed any better. This results from the fact that a promise can be rejected by throwing inside thenor 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.

目前Promise无法更好地输入。这是因为一个承诺可以被throwing inside thenor拒绝catch(这是拒绝现有承诺的一种更好的方式),而这不能通过类型系统来处理;此外,TypeScript 也没有特定于异常的类型,除了never.

回答by Mikhail Vasin

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.

异常类型为 any 是因为我们无法在设计时保证异常的正确类型,并且 TypeScript 和 JavaScript 都没有提供在运行时保护异常类型的能力。 您最好的选择是使用类型保护在您的代码中提供设计时和运行时检查。

source

来源

回答by RAM

What @EstusFlask mentioned in his answeris correct.

@EstusFlask 在他的回答中提到的是正确的。

ButI want go one step near to an artificial solutionto simulatewhat we want with TypeScriptcapabilities.

我想更接近人工解决方案,模拟我们想要的TypeScript功能。

?

?

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)
    }
})

回答by KEIII

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:

因为在某些情况下无法设置错误类型,例如 Promise 或异常抛出,我们可以以类似 rust 的方式处理错误:

// Result<T, E> is the type used for returning and propagating errors.
// It is an sum type with the variants,
// Ok<T>, representing success and containing a value, and 
// Err<E>, representing error and containing an error value.
export type Ok<T> = { _tag: "Ok"; ok: T };
export type Err<E> = { _tag: "Err"; err: E };
export type Result<T, E> = Ok<T> | Err<E>;
export const Result = Object.freeze({
  Ok: <T, E>(ok: T): Result<T, E> => ({ _tag: "Ok", ok }),
  Err: <T, E>(err: E): Result<T, E> => ({ _tag: "Err", err }),
});

const start = (): Promise<Result<string, number>> => {
  return new Promise((resolve) => {
    resolve(someCondition ? Result.Ok("correct!") : Result.Err(-1));
  });
};

start().then((r) => {
  switch (r._tag) {
    case "Ok": {
      console.log(`Ok { ${r.ok} }`);
      break;
    }
    case "Err": {
      console.log(`Err { ${r.err} }`);
      break;
    }
  }
});