理解Typescript中的复杂类型声明

时间:2017-05-21 20:35:08

标签: typescript types visual-studio-code typescript2.0 typescript2.3

查看此类型声明:

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是一个可信/承诺,而在此背景下

const val2 = await announce(..)

val2的类型为MessagesSendResponse

我的问题是我对Thenable界面不了解以下内容:

  1. Thenable<U>是什么意思我明白U是通用类型,但Thenable<U>是什么意思?写这个的另一种方式是什么?

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

  3. 我意识到问题2反映了我的困惑。任何链接到引用赞赏,我找不到任何类似于这种模式。

2 个答案:

答案 0 :(得分:2)

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

因为promises通常用于异步操作,所以promise不会“返回一个值”,但会为你提供一个API来获取对该值的引用。

then / catch返回Thenable<T>的原因是您可以将调用链接起来:

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

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

then / catch返回的承诺与您调用函数的承诺不同,它是一个新实例,编译器根据此新承诺推断出通用类型在您传递的函数的返回值上,例如:

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

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

编译器知道str类型为stringnum类型为number

您可以在此处详细了解此流程:promise chaining in MDN

修改

在签名中:

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

<强> onFulfilled
需要类型为R的值的函数,并返回类型为UThenableU的值。

<强> onRejected
需要类型为any的值的函数,并返回类型为UThenableU的值。

<强>返回
Thenable的实例,其类型为U,这是执行onFulfilledonRejected的结果。

答案 1 :(得分:1)

1部分:

export interface Thenable<R> {

我们使用一个类型参数R

定义通用接口

2部分:

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

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

第3部分,最有趣的一个:

使用此类型声明

onFulfilled

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

这意味着它是一个功能R和返回U,或另一个Thenable<U>

以下是RU之间的关系:如果您有Thenable<R>,则then方法接受一个回调,该回调使用类型{{1}的值调用(原始可生成的那个),并且应该返回R。或者它可以接受另一个U

Thenable<U>方法的返回值为then

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