在TypeScript中,为什么可以';异步函数返回类型为t | Promise<;T>;?

在TypeScript中,为什么可以';异步函数返回类型为t | Promise<;T>;?,typescript,promise,async-await,union-types,Typescript,Promise,Async Await,Union Types,我正在用typescript构建一个API,一些控制器动作可以是同步的,而另一些则不能。我想指定如下响应类型: type ActionResult =IHttpActionResult | Promise<IHttpActionResult>; async符号是对以下内容的语法糖: 此函数将始终返回承诺 即使您声明: const foo = async() => 3; 它基本上与以下内容相同(尽管更严格): 或作为: const foo = () => Promise

我正在用typescript构建一个API,一些控制器动作可以是同步的,而另一些则不能。我想指定如下响应类型:

type ActionResult =IHttpActionResult | Promise<IHttpActionResult>;

async
符号是对以下内容的语法糖:

此函数将始终返回承诺

即使您声明:

const foo = async() => 3;
它基本上与以下内容相同(尽管更严格):

或作为:

const foo = () => Promise.resolve(3);
所有这些例子都将回报一个承诺

主要区别在于,“普通”函数可以返回承诺和其他类型,但一旦使用了
async
,它总是会返回承诺

即使承诺立即得到解决,
async
函数也无法不通过设计返回承诺

你得等一等,然后用它

这也在以下文件中说明:

异步函数声明定义了一个异步函数,该函数 返回一个AsyncFunction对象。异步函数是一个 函数,该函数使用 含蓄地承诺返回结果。但是 使用异步函数的代码更像是使用标准函数 同步功能

特别是在返回类型上:

将使用异步函数返回的值解析的承诺 函数,或被拒绝,并从内部引发未捕获的异常 异步函数


考虑到这一点,我建议将API设置为默认的异步。如果你的某些行为是同步的,对外界来说并不重要。在那种情况下,你可以马上解决这个问题。您不需要输入StringyThingy=string | Promise

根据
Promise
键入,让async为您处理包装成Promise的过程,或者在真正的async用例中实际返回其他承诺。这样,您不必检查promise的实例,但您将以相同的方式处理异步/同步分支


如果您真的想要联合类型(我真的不建议这样),那么您必须放弃使用
async
关键字

您可以定义返回以下任一类型的普通函数:

const foo = (x:number): Promise<number>|number => {
    if(x >=0) {
         return new Promise(resolve => resolve(x));
    } else {
         return x;
    }
}
constfoo=(x:number):承诺| number=>{
如果(x>=0){
返回新承诺(resolve=>resolve(x));
}否则{
返回x;
}
}

评论不用于扩展讨论;这段对话是相关的:评论不是为了进一步讨论;这段对话已经结束。
const foo = () => new Promise(resolve => resolve(3));
const foo = () => Promise.resolve(3);
const foo = (x:number): Promise<number>|number => {
    if(x >=0) {
         return new Promise(resolve => resolve(x));
    } else {
         return x;
    }
}