【问题标题】:Typescript function that accepts only functions returning the same type只接受返回相同类型的函数的打字稿函数
【发布时间】:2020-01-05 20:34:23
【问题描述】:

我想创建一个函数check(f),其中参数f必须是返回与其参数相同类型的函数,类型会被推断出来。例如:

check((v: number) => v + 1); // OK
check((s: string) => s.toLowerCase()); // OK
check((v: number) => v.toString()); // Not OK

我尝试了以下方法:

function check<T>(f: (v: T) => T) { }

check((v: number) => v > 10 ? v : ""); // Shouldn't be OK

奇怪的是,这段代码确实在 TypeScript playground(运行 TypeScript 3.5.1)中报告了错误,但在我的 VS Code(运行 TypeScript 3.6.2)中却没有,它推断出通用参数T&lt;number | ""&gt;。发生这种情况是因为一些最新的变化吗?如果是这样,我怎样才能编写所需的check 函数?

更新

以下是重现问题的步骤:

  1. 创建一个空文件夹。
  2. 在文件夹内创建文件test.ts,内容为上面的示例代码。文件夹中没有其他文件,因此没有 tsconfig.json,因此所有设置都是默认设置。
  3. 用VS Code打开文件夹,打开test.ts。编辑器显示代码没有错误。将光标悬停在check函数上方表明推断为check&lt;number | ""&gt;
  4. 打开控制台并运行tsc test.ts。构建成功,没有错误。

【问题讨论】:

  • 我想我没有得到你想要的。支票的返回类型应该是什么?
  • @JohnnyZabala check 返回void。不用担心check 究竟做了什么,它主要用作类型保护。
  • 好吧,您可以明确设置泛型类型:check&lt;number&gt;((v: number) =&gt; v &gt; 10 ? v : ""));,这应该会失败。但是,如果没有它,它也应该失败......
  • @HereticMonkey 这个想法是我希望check 自动推断f 的类型。是的,我同意它应该在没有明确分配T 的情况下失败,我不知道为什么它没有。
  • 我实际上认为它在做正确的事情;它推断T 的最广泛类型,因为没有指导,它必须这样做。它不能仅仅因为您将它用于v 而假设number。但我要让漫游这些虚拟大厅的一位 TS 专家回答:)。

标签: typescript typescript-generics


【解决方案1】:

您的问题是您没有使用--strict 编译器选项;具体来说,您需要启用the --strictFunctionTypes option 才能开始收到您期望的错误。它与 TypeScript 的 3.5 和 3.6 版本无关。你(也许是无意的)要求参数二元性,这就是你得到的。

如果--strictFunctionTypes 关闭,那么函数将不安全地成为bivariant in their parameter types,这意味着您可以缩小它们接受的类型。 加宽他们接受的类型是安全的(因为接受number | ""的每个函数也是接受number的函数,如果我期望后者,你可以给我前者)但它缩小它是不安全的(因为不是每个接受number的函数也是接受number | ""的函数,如果我期待后者,你真的不应该给我前者) .尽管如此,在某些情况下,双变量很有用是不安全的,因此它的某种形式可能会在 TypeScript 中存在,至少会存在一段时间,并且可能会永远存在以实现向后兼容性。

除非您想要参数双变量,否则您应该打开--strictFunctionTypes,并且可能只打开--strict。希望这能满足您的需求。好的;希望有帮助。祝你好运!

【讨论】:

    猜你喜欢
    • 2015-08-10
    • 2022-01-12
    • 2019-07-16
    • 2021-12-17
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多