ParsedAuthorizationResponse 不是一个类(这就是new 不起作用的原因),它是一个类型。在这种情况下,它是一堆不同的可能对象形状。一起来看看
export type ParsedAuthorizationResponse =
| IAuthResponse<
{ processorTransactionId: string },
'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED'
>
| IAuthResponse<{ declineReason: string }, 'DECLINED'>
| IAuthResponse<{ errorMessage: string }, 'FAILED'>;
对,这告诉我们ParsedAuthorizationResponse 只是IAuthResponse 的三种不同参数化中的任何一种的同义词。不幸的是,在我们知道IAuthResponse 的样子之前,这并不能告诉我们太多。幸运的是,我们做到了:
type IAuthResponse<T, U extends TransactionStatus> = T & {
transactionStatus: U;
};
好的,这变得更具体了。 TransactionStatus 只是几个字面量字符串的同义词,而T & { transactionStatus: U; } 是一个类型连词,意味着结果是一个类型,就像T 类型一样,加上一个字段transactionStatus 属于 U 类型(与 U extends TransactionStatus 一起被限制为我们称为 TransactionStatus 的一个或多个字符串)。
那么IAuthResponse<{ errorMessage: string }, 'FAILED'> 是什么意思?好吧,看看IAuthResponse,它扩展为:
{ errorMessage: string } & { transactionStatus: 'FAILED' }
与
相同
{ errorMessage: string; transactionStatus: 'FAILED' }
这意味着ParsedAuthorizationResponse 实际上看起来像这样:
type ParsedAuthorizationResponse =
| { processorTransactionId: string; transactionStatus: 'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED' }
| { declineReason: string; transactionStatus: 'DECLINED' }
| { errorMessage: string; transactionStatus: 'FAILED' }
所以,创建一个符合ParsedAuthorizationResponse 的对象真的很简单,它只是对象字面量:
- 如果失败,它是一个带有
transactionStatus: 'FAILED' 和任意errorMessage 字符串的对象
- 如果它被拒绝,您有
transactionStatus: 'DECLINED' 和任意 declineMessage 字符串
- 否则,它的
transactionStatus 设置为'AUTHORIZED'、'CANCELLED'、'SETTLING' 或'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 };
}
}