让我们看一个例子:
export async function foo(): Promise<string>{
await bar()
return;
}
编译没有错误。
然后,
export async function foo(): Promise<string>{
await bar()
}
导致错误
声明类型既不是&#39;无效的函数。也没有任何&#39;必须返回一个值
1)为什么?
我想这是https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#63-function-implementations
并使用async,typescript及其输入复杂化?
更新:
仅供参考,当函数return;
没有return
(或甚至有return undefined;
)时,从语义角度看它是相同的情况,对吗?
答案 0 :(得分:4)
这与async/await
无关,空回报被视为return undefined
。所以这也有效:
function foo(): string{
return; // equivalent to return undefined;
}
如果您使用strictNullChecks
,则会因undefined
无法分配string
而收到错误
如果完全省略返回,编译器会将返回类型推断为void
,这与声明的string
类型不同,因此这将是一个错误。如果函数为async
并返回Promise
答案 1 :(得分:2)
明确提供Void
或Any
以外的返回类型的关键是您要确保类型安全。你隐含地告诉编译器你真的想要返回一些东西。这就是为什么编译器希望你这样做,并在你不这样做时抱怨。它在TypeScript规范section 6.1中定义:
返回类型不是Void类型,Any类型或包含Void或Any类型作为组成部分的union类型的显式类型函数必须在其主体的某处包含至少一个return语句
至于你关于return
的问题,你是对的。
return;
和return undefined;
具有相同的结果,由ECMAScript规范section 13.10定义:
如果省略Expression,则返回值未定义。
省略return
语句也具有与section 9.2.1中定义的相同的效果。步骤11基本上表示如果没有返回任何其他内容,则返回undefined
(步骤9)或者没有抛出任何异常(步骤10)。
因此,虽然您的示例在JavaScript中导致相同的结果(返回undefined
),但它们对于TypeScript编译器在语义上是不同的(第二个例子不会返回任何内容)。
答案 2 :(得分:1)
如果您不打算退回Promise,则必须使用Promise<void>
。
答案 3 :(得分:1)
通过使用返回类型注释(: Promise<string>
),您说该函数将返回一些东西(可能在将来某个点解析为字符串的Promise),因此没有return
的函数陈述明显违背了该注释/意图。
要将函数标记为不返回任何内容,您可以使用注释: void
,但这可能会导致不能将未定义强制转换为Promise的错误,因此在这种情况下{{1可能更合适。
在您的示例中,您有一个空: Promise<void>
表达式并不重要,因为使用return
函数,如果您返回一个非承诺值,它将自动包含在一个承诺中,所以async
从编译器的角度来看仍然是正确的。