理解 Typescript 中的复杂类型声明

Understanding complex type declaration in Typescript

查看此类型声明:

export interface Thenable<R> {
    then<U>(onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Thenable<U>
    then<U>(onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => void): Thenable<U>
    catch<U>(onRejected?: (error: any) => U | Thenable<U>): Thenable<U>
}

我知道它的作用。我可以这样做:

type MessagesSendResponse = ...
export const announce = (options: sendParameters):Thenable<MessagesSendResponse> => {
 return Promise.all([emailMessage(options),smsMessage(options)] 
}

这使得它足够聪明,可以在上下文中知道

const val1 = announce(..)

val1 是 Thenable/Promise 而在这种情况下

const val2 = await announce(..)

val2 的类型是 MessagesSendResponse

我的问题是我不理解以下关于 Thenable 接口的内容:

  1. Thenable<U> 是什么意思 我知道 U 是泛型,但 Thenable<U> 是什么意思?还有什么写法?

  2. 这个定义不知何故是说函数 return 是一个 thenable / promise,而后者又 return 是一个泛型。然而,thencatch 的接口类型和 return 值都是 Thenable<U> 类型。看起来它说它 returns 本身,我认为这是正确的,因为一个 thenable 可以 return 另一个 thenable,但是它怎么知道它知道分辨率是 MessagesSemdResponse 如果它说 returns Thenable<U>? IDE 中有一些内置功能吗?

我意识到问题 2 反映了我的困惑。感谢任何指向参考的链接,我找不到与此模式类似的内容。

Thenable<T> 表示您有一个对象,您可以从中获取类型为 T.
的值 或者,如果将其命名为 Promise<T>,您将获得对 T.

类型值的承诺

因为 promise 通常用于异步操作,所以 promise 不会 "return a value" 但会为您提供 api 以便在该值可用时获取对该值的引用。

then/catch return Thenable<T> 的原因是您可以链接调用:

announce(...).then(value => {
    ...
}).catch(error => {
    ...
});

当值可用或出现错误时,将调用您传递给 then/catch 的函数。

return由 then/catch 编辑的承诺与您调用该函数的承诺不同,它是一个新实例,编译器推断这个新承诺的通用类型基于您传递的函数的 return 值,例如:

const fn = (): Promise<string> => {
    return Promise.resolve("43"); 
}

fn().then(str => Number(str)).then(num => console.log(num))

编译器知道 strstring 类型,numnumber.

类型

您可以在此处阅读有关此过程的更多信息:promise chaining in MDN


编辑

签名中:

then<U>(onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Thenable<U> 

onFulfilled:
一个函数,它需要一个 R 类型的值,并且 return 是一个 U 类型的值或 ThenableU.

onRejected:
一个函数,它需要 any 类型的值和 return 类型的值 UThenableU.

returns:
U 类型值的 Thenable 实例,它是 onFulfilledonRejected.

的执行结果

第 1 部分:

export interface Thenable<R> {

我们正在用一个类型参数定义通用接口R

第 2 部分:

then<U>(onFulfilled?: ...,  onRejected?: ...): ...

它有方法 then,它有两个参数 onFulfilledonRejected,方法本身是通用的 - 它依赖于另一个类型参数 U

第三部分,最有趣的:

onFulfilled 使用此类型声明:

(value: R) => U | Thenable<U>

这意味着它要么是一个接受 R 和 returning U 的函数,要么是另一个 Thenable<U>

这里是 RU 之间的关系:如果你有 Thenable<R>,它的 then 方法接受一个回调,它被调用的值类型为 R(原来thenable产生的那个),应该return U。或者它可以接受另一个 Thenable<U>.

这个then方法的return值为Thenable<U>

简而言之,这就是用类型描述承诺链的方式。