What I can't figure how is how ParsedAuthorizationResponse is implemented and how I can set it's values differently. Eventually, I want to return a certain value/type as a promise.
I thought this would work but it doesn't
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>;
ParsedAuthorizationResponse
isn't a class (which is why new
doesn't work), it's a type . In this case, it's a bunch of different possible object shapes. Let's have a look
export type ParsedAuthorizationResponse =
| IAuthResponse<
{ processorTransactionId: string },
'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED'
>
| IAuthResponse<{ declineReason: string }, 'DECLINED'>
| IAuthResponse<{ errorMessage: string }, 'FAILED'>;
Right, this tells us that ParsedAuthorizationResponse
is just a synonym for any one of three different parametrizations of IAuthResponse
. Unfortunately, that doesn't tell us much until we know what IAuthResponse
looks like. Which we do, fortunately:
type IAuthResponse<T, U extends TransactionStatus> = T & {
transactionStatus: U;
};
OK, this gets more concrete. TransactionStatus
is just a synonym for a couple of literal strings, and T & { transactionStatus: U; }
T & { transactionStatus: U; }
is a type conjunction , meaning that the result is a type that is just like the type T
, plus a field transactionStatus
which is of type U
(which with U extends TransactionStatus
is constrained to be one or more of the strings we know as TransactionStatus
).
So what does something like IAuthResponse<{ errorMessage: string }, 'FAILED'>
mean? Well, looking at IAuthResponse
, it expands to this:
{ errorMessage: string } & { transactionStatus: 'FAILED' }
which is the same as
{ errorMessage: string; transactionStatus: 'FAILED' }
Which means that ParsedAuthorizationResponse
actually looks like this:
type ParsedAuthorizationResponse =
| { processorTransactionId: string; transactionStatus: 'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED' }
| { declineReason: string; transactionStatus: 'DECLINED' }
| { errorMessage: string; transactionStatus: 'FAILED' }
So, creating an object conforming to ParsedAuthorizationResponse
is really easy, it's just object literals:
transactionStatus: 'FAILED'
and an arbitrary errorMessage
stringtransactionStatus: 'DECLINED'
and an arbitrary declineMessage
stringtransactionStatus
set to one of 'AUTHORIZED'
, 'CANCELLED'
, 'SETTLING'
, or 'SETTLED'
, plus a processorTransactionId
which is a string that I assume you get along with the status of the transaction.Your example would end up something like this:
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 };
}
}
Returning a promise type is very easy and is not different then returning a promise of a primitive.
Any value you return from an async
function will be wrapped with a promise, so:
const returnsANumber = async (): Promise<number> => {
return 42
}
type Foo = {
foo: true
}
const returnsAFoo = async (): Promise<Foo> => {
return {
foo: true
}
}
In your case just return a ParsedAuthorizationResponse
First, as @thedude said, because your function is already async
there is no need to return a Promise, whatever you return will be automatically turned into a Promise.
Now to answer: "How to return a ParsedAuthorizationResponse
".
Starting with the (part of) defintion:
export type ParsedAuthorizationResponse =
| IAuthResponse<
{ processorTransactionId: string },
'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED'
>
(I'm only going to do this logic with one example of ParsedAuthorisationResponse in the hope you can do the rest)
This says that it's an IAuthResponse<T, U>
where T is { processorTransactionId: string }
and U is 'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED'
'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED'
Slotting this into the defintion of IAuthResponse gives us
type IAuthResponse<T, U extends TransactionStatus> = {
processorTransactionId: string,
transactionStatus: 'AUTHORIZED' | 'CANCELLED' | 'SETTLING' | 'SETTLED';
};
Meaning an example of ParsedAuthorizationResponse
is
{
processorTransactionId: "any old string",
transactionStatus: 'AUTHORIZED',
}
So to return it from your function use something like:
async authorize(
request: RawAuthorizationRequest<ClientIDSecretCredentials, PayPalOrder>,
):ParsedAuthorizationResponse {
//just imagine I'm gonna get a response that has a value of status in it
const { status } = JSON.parse(await response)
return {
processorTransactionId: status, // or whatever
transactionStatus: 'AUTHORIZED',
};
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.