如何在 TypeScript 中使用此自定义类型返回 Promise?

raj*_*ase 2 javascript return-type type-conversion typescript typescript-generics

我无法弄清楚 ParsedAuthorizationResponse 是如何实现的,以及我如何以不同的方式设置它的值。最终,我想返回某个值/类型作为承诺。

我以为这会奏效,但没有

let PAR; 
if (status === 'COMPLETED') { 
PAR = new ParsedAuthorizationResponse('AUTHORIZED')
} else throw new Error('Authorization failed')

return Promise<PAR>;
}

//Also tried this but didn't work

type ParsedAuthorizationResponse PAR = 'AUTHORIZED';
return new Promise<PAR>;
Run Code Online (Sandbox Code Playgroud)

gus*_*afc 5

ParsedAuthorizationResponse不是一个(这就是为什么new不起作用),它是一个类型。在这种情况下,它是一堆不同的可能对象形状。我们来看一下

  export type ParsedAuthorizationResponse =
  | IAuthResponse<
      { processorTransactionId: string },
      'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED'
    >
  | IAuthResponse<{ declineReason: string }, 'DECLINED'>
  | IAuthResponse<{ errorMessage: string }, 'FAILED'>;
Run Code Online (Sandbox Code Playgroud)

是的,这告诉我们ParsedAuthorizationResponse只是 的三种不同参数化中任何一种的同义词IAuthResponse。不幸的是,在我们知道IAuthResponse看起来像什么之前,这并不能告诉我们太多信息。我们所做的,幸运的是:

type IAuthResponse<T, U extends TransactionStatus> = T & {
  transactionStatus: U;
};
Run Code Online (Sandbox Code Playgroud)

好的,这变得更具体了。TransactionStatus仅仅是几个文字串的同义词,并且T & { transactionStatus: U; }是一种类型结合,这意味着结果是一类是一样的类型T,再加上一个字段transactionStatus,其是式U(其与U extends TransactionStatus被限制为一个或多个的我们知道的字符串TransactionStatus)。

那么likeIAuthResponse<{ errorMessage: string }, 'FAILED'>是什么意思呢?好吧,看着IAuthResponse,它扩展到:

{ errorMessage: string } & { transactionStatus: 'FAILED' }
Run Code Online (Sandbox Code Playgroud)

这与

{ errorMessage: string; transactionStatus: 'FAILED' }
Run Code Online (Sandbox Code Playgroud)

这意味着ParsedAuthorizationResponse实际上看起来像这样:

type ParsedAuthorizationResponse =
      | { processorTransactionId: string; transactionStatus: 'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED' }
      | { declineReason: string; transactionStatus: 'DECLINED' }
      | { errorMessage: string; transactionStatus: 'FAILED' }
Run Code Online (Sandbox Code Playgroud)

所以,创建一个符合 的对象ParsedAuthorizationResponse真的很容易,它只是对象字面量:

  • 如果失败,它是一个带有transactionStatus: 'FAILED'和 任意errorMessage字符串的对象
  • 如果它被拒绝,你有transactionStatus: 'DECLINED'一个任意的declineMessage字符串
  • 否则,它已transactionStatus设置为'AUTHORIZED', 'CANCELLED', 'SETTLING', or 之一'SETTLED',加上 processorTransactionId一个字符串,我假设您与交易状态相处融洽。

你的例子最终会是这样的:

  async authorize(
    request: RawAuthorizationRequest<ClientIDSecretCredentials, PayPalOrder>,
  ): Promise<ParsedAuthorizationResponse> {
      // The response needs to contain status and transaction ID
      const { status, processorTransactionId } = JSON.parse(await response) as { status: string; processorTransactionId: string; }
      switch (status) {
        case 'COMPLETE':
          return { transactionStatus: 'AUTHORIZED', processorTransactionId };
        case 'VOIDED':
          return { transactionStatus: 'CANCELLED', processorTransactionId };
        // TODO: Fill in more cases here...
        default: 
          // Unknown status, hopefully shouldn't happen, but for the sake of
          // argument, let's pretend that failing the transaction is a reasonable
          // thing to do here, just to show how to return an error message
          return { transactionStatus: 'FAILED', errorMessage: 'Unknown status: ' + status };
      }
    }
Run Code Online (Sandbox Code Playgroud)