Typescript 函数可以将 Promise<any> 作为 Promise<Bar> 返回吗?

Posted

技术标签:

【中文标题】Typescript 函数可以将 Promise<any> 作为 Promise<Bar> 返回吗?【英文标题】:Typescript function can return Promise<any> as Promise<Bar>? 【发布时间】:2019-08-16 04:11:11 【问题描述】:

我正在为 fetch-api 创建一个类型安全的包装器,我注意到 typescript 编译器将其归类为完全有效的代码:

function foo(response: Response): Promise<Bar>  //response received from a fetch() call
    const json: Promise<any> = response.json();
    return json; //Promise<any> can be returned as Promise<Bar>?

为什么可以将Promise&lt;any&gt; 直接返回为Promise&lt;Bar&gt;?这不应该需要某种类型的断言吗?

【问题讨论】:

【参考方案1】:

始终避免anyany 根据定义可以分配给任何东西,并且可以从任何东西分配,而无需任何类型的断言。当用作泛型类型参数时,结果类型(例如Promise&lt;any&gt;)通常可以分配给在该位置具有任何其他类型参数的任何其他实例化(例如Promise&lt;Bar&gt;)。

自从 3.0 typescript 引入了 unknown(更多信息请阅读 here),它与 any 类似,您可以为其分配任何东西,如果没有类型断言,它就不能分配给其他任何东西。所以这是一个错误:

let u: Promise<unknown>
let n: Promise<number> = u; // error

您还可以查看 tslint 规则 no-unsafe-anyno-any 以防止在项目中使用 any,这取决于您想在多大程度上禁止 any,就像我在开始时所说的那样将完全禁止它,并在绝对必要的少数情况下添加例外。

【讨论】:

这很有意义。 Body.json() 返回 Promise&lt;any&gt; 而不是 Promise&lt;unknown&gt; 有什么原因吗? @superbadcodemonkey 如果这样做会破坏很多代码。有一个 GH 讨论添加一个选项以在 lib.d.ts 中使用 unknown 而不是 any 但我现在找不到它,我认为它不会很快实施。【参考方案2】:

如果某物可以是anything,它也可以是Bar。如果您查看 Basic Types 的 Typescript 文档,它会说(强调我的)

任何

我们可能需要描述我们在编写应用程序时不知道的变量类型。这些值可能来自动态内容,例如来自用户或第三方库。在这些情况下,我们希望退出类型检查并让值通过编译时检查。为此,我们将它们标记为 any 类型:

这意味着any 类型完全忽略了编译时类型检查。

【讨论】:

以上是关于Typescript 函数可以将 Promise<any> 作为 Promise<Bar> 返回吗?的主要内容,如果未能解决你的问题,请参考以下文章

重构typescript云函数使用promise chaining

typescript async函数必需返回promise么

当我从等待移动到 Promise.all 时,TypeScript 函数返回类型错误

使用 angularJS 和 Typescript 的 Promise

什么 AsyncGenerator TypeScript 类型会产生 Promise?

typeScript函数篇