当前位置: 首页 > 知识库问答 >
问题:

前端 - TypeScript 中,Promise 的 reject 无法使用类型推导吗?

方野
2024-01-29

遇到一个 TypeScript 中有关 Promise 的类型推导问题:

以下代码中,resolve 会有明确的类型限制,但 reject 却没有,想知道如何才能做到?

type P1 = Promise<number>;const p1: P1 = new Promise((resolve, reject) => {  // Expected 1 arguments, but got 0. Did you forget to include 'void' in your type argument to 'Promise'?ts(2794)  resolve();  resolve(1);  // Argument of type 'string' is not assignable to parameter of type 'number | PromiseLike<number>'.ts(2345)  resolve("str");  reject();  reject(123);  reject("str");});

image.png

查看 Promise 的类型声明

image.png

只有一个泛型参数,貌似不支持。
找到了这篇文章,文章的结论是:无法定义,也无需定义。

Typescript 中 Promise reject 的类型该如何定义?

希望 reject 也能有明确的类型推导,但貌似原理上不可行。

那么,在处理 catch 的时候,编辑器报出来的 any,应该怎么处理比较优雅呢?

p1.catch((err: any) => {})

除了在这里直接声明,还有什么最佳实践吗?

共有2个答案

司迪
2024-01-29

我也提供一个解决方案吧

const p1 = new Promise((resolve, reject) => {  setTimeout(() => {    resolve(1)  }, 1000)});class ErrorModel<T = void>{  detail?: T;  timeTemp?: number;  constructor(error: Partial<ErrorModel>) {    Object.assign(      this,      error,      {        timeTemp: Date.now()      })  }  log() {    console.log('error', JSON.stringify(this.detail || {}));  }}export class CallModel<T = void, E = void>{  data?: T;  error?: ErrorModel<E>;}function Callback<D, E>(promise: Promise<D>) {  return promise    .then<CallModel<D>>((data) => ({ data }))    .catch<CallModel<D, E>>((error) => ({ error })) as Promise<CallModel<D, E>>;}Callback<number, string>(p1 as Promise<number>).then(({ data, error }) => {  if(error){    error?.log();    return;  }  //  resulut  console.log(data!);})
段干靖
2024-01-29

这个是设计如此吧,毕竟你确实可能不知道会 catch 到什么错误

不过好像可以包装一个确定错误类型的 PromiseE

type Nullable<T> = T | null | undefinedtype MaybePromiseLike<T> = T | PromiseLike<T>class PromiseE<T, E = any> extends Promise<T> {  constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: E) => void) => void) {    super(executor)  }  catch<R = never>(onrejected?: ((reason: E) => R | PromiseLike<R>) | undefined | null): Promise<T | R> {    return super.catch(onrejected)  }}const p = new PromiseE<number, string>((res, rej) => {  res(1)  // @ts-expect-error  rej(2)  rej('3')})p.catch(err => {  err // err: string})
 类似资料:
  • 想实现value是string那么val就是string,value是string[]那么val就是string[]

  • 在写单元测试中,我想抽象一个通用的函数,避免重复书写。函数的定义如下: 但是我不知道如果建立 fn 函数参数的类型和 source 类型之间的联系。 请问要怎么写才可以让 source 的类型等于 fn 参数类型的数组?

  • 通常看到定义一个 promise 的类型都采用 Promise<string> 的方式,表示 resolved 时返回一个 string 的类型值,但是会忽略 rejected 后应该返回什么类型,这是故意这么设计的吗?

  • TypeScript 类型检查机制包含三个部分: 类型推断 类型保护 类型兼容性 本节介绍其中的类型推断,类型推断主要用于那些没有明确指出类型的地方帮助确定和提供类型,这是 TypeScript 的一种能力。 类型推断是有方向的,要注意区分从左向右和从右向左两种推断的不同应用。 1. 慕课解释 类型推断的含义是不需要指定变量类型或函数的返回值类型,TypeScript 可以根据一些简单的规则推断其

  • 这节介绍TypeScript里的类型推论。即,类型是在哪里如何被推断的。 基础 TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型。如下面的例子 var x = 3; 变量x的类型被推断为数字。 这种推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时。 大多数情况下,类型推论是直截了当地。 后面的小节,我们会浏览类型推论时的细微差别。 最佳通用类型 当需要从几