Exploring the intricacies of this type declaration:
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>
}
I have a good grasp of its function. For instance, I can utilize it like so:
type MessagesSendResponse = ...
export const announce = (options: sendParameters):Thenable<MessagesSendResponse> => {
return Promise.all([emailMessage(options),smsMessage(options)]
}
This setup allows for distinction between contexts:
const val1 = announce(..)
where val1
is recognized as a Thenable/Promise, while in this scenario
const val2 = await announce(..)
val2
is identified as type MessagesSendResponse
The aspect that puzzles me regarding the Thenable
interface is:
What does it signify when stating
Thenable<U>
? I comprehend thatU
represents a generic type, but what is conveyed byThenable<U>
? Is there an alternate way to express this?In some way, this definition specifies that a function yields a thenable/promise which subsequently returns a generic value. However, both the interface type and the return value for both
then
andcatch
are labeled asThenable<U>
. It seems to indicate that it returns itself, considering a thenable can produce another thenable, but how does it recognize that the outcome isMessagesSemdResponse
if it declares to yieldThenable<U>
? Is there a built-in feature in the IDE aiding with this?
This query stems from my confusion about question 2. Any suggestions or references related to this pattern would be greatly appreciated, as I could not locate similar information in my research.