Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
99 views
in Technique[技术] by (71.8m points)

javascript - How do I return a Promise with this custom type in TypeScript?

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>;
question from:https://stackoverflow.com/questions/66048477/how-do-i-return-a-promise-with-this-custom-type-in-typescript

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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; } 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:

  • If it's failed, it's an object with transactionStatus: 'FAILED' and an arbitrary errorMessage string
  • If it's declined, you have transactionStatus: 'DECLINED' and an arbitrary declineMessage string
  • Else, it has transactionStatus 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 };
      }
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...