I have have some types like tihs
export interface Result<T> { data: T};
export type ErrorResult = Result<string>;
export type ErrorResponse = Promise<ErrorResult>;
export type SuccessResult = Result<any>;
export type SuccessResponse = Promise<SuccessResult>;
Why won't TS let me write a function like
export async function stuff(): ErrorResponse | SuccessResponse {}
It will only let me do
export async function stuff(): Promise<ErrorResult | SuccesResult> {}
CodePudding user response:
In JavaScript, a function declared as async
always returns a Promise
. That promise can be await
-ed to retrieve a value of the internal type. (Read more on MDN)
E.g.
async function getName() {
// Example internals..
return "Celine";
}
const theNamePromise = getName();
// ^^ This is a Promise<string>
const theName = await getName();
// this is a string ("Celine")
Edit: More specific to your example:
(Note, I don't actually have a convincing answer here. But I did some tinkering and found some mildly interesting things. The below is a very short write-up of what I found, and here is the example code I was playing with)
It's important to note that Promise<string> | Promise<number>
and Promise<string | number>
are close, but not entirely equivalent as far as TypeScript is concerned.
To explain with an example, suppose we take your Result<T>
type and used it similarly:
function getResult(): Result<string> | Result<number> {
// This return statement yields a TS error
return {
data: Math.random() > 0.5 ? "test" : 5,
};
}
If you plug this into TS, you'll get an error, because the value being returned is of type { data: string | number; }
, not { data: string; } | { data: number; }
.
That type is assignable to Result<string | number>
function getResult2(): Result<string | number> {
// This is valid
return {
data: Math.random() ? "test" : 5,
};
}
Now, this highlights a difference between how TS sees these types, but doesn't necessarily explain why the top-level type returned by an async
can't be an intersection between two Promise<T>
types. Afraid I don't have a thorough answer there.