【问题标题】:Define a function that returns a function that returns void定义一个返回函数的函数,该函数返回 void
【发布时间】:2021-12-18 07:45:03
【问题描述】:

我不明白为什么会报错

function foo(): () => string {
  return () => 123;
}

但这不是

function foo(): () => void {
  return () => 123;
}

而且这也不会出错

function foo(): (a: number) => string {
  return () => '123';
}

我明确键入返回的函数应该接受一个参数,然后返回一个不接受任何参数的函数,但 TS 没有给我任何错误。

【问题讨论】:

  • 因为一个数字可以忽略(void),但不是string。
  • @Bergi 您能否在评论中提供更多解释?很难理解你的意思。
  • 等等,你是在问两个问题吗?您从“还有……”开始,这似乎是关于不同代码的第二个问题。 Please limit each post to one question。此外,您的第二个问题似乎是在第一个问题已经得到答案之后被编辑的。 Please do not add followup questions to existing questions。第二个问题的正确做法是创建一个新帖子。

标签: javascript typescript typescript-typings


【解决方案1】:

将() => number 类型的函数分配给() => string 类型的东西显然是一个类型错误。但是,对于 void 作为返回类型,TypeScript 更为宽松。来自the handbook on the Assignability of Functions:

void 函数的返回类型可能会产生一些异常,但 预期的行为。

返回类型为void 的上下文类型不强制函数 不返回一些东西。另一种说法是上下文 具有void 返回类型 (type vf = () => void) 的函数类型,当 已实现,可以返回任何其他值,但会被忽略。

[…]

还有一种特殊情况需要注意,当一个字面量 函数定义具有void 返回类型,该函数必须不 返回任何东西。

还有一个关于它的FAQ entry。

【讨论】:

  • 我已经阅读了文档,他们说:这种行为存在,因此即使 Array.prototype.push 返回 number 并且 Array.prototype.forEach 方法需要一个具有void 的返回类型。这样Array.prototype.forEach 应该期望返回类型为any 的函数不是更合乎逻辑吗
  • @fires3as0n 是的。 forEach 需要 (value: T, index: number, array: T[]) => void 类型的参数,而 TypeScript 的设计使得 (value: T) => number 可以分配给它。
  • @fires3as0n any 表示“轮到类型检查,忽略错误”。不是一个好习惯。 void 特别保证forEach 不会使用返回值。
  • 对我来说仍然听起来不合逻辑。首先,看起来使用返回 void 的函数的返回值不会给出错误,只会给出警告。其次,关于主题问题:我们如何定义一个返回不应该返回任何东西的函数的函数。用 Typescript 做不到吗?
  • @fires3as0n 看看从那里链接的How to allow a function return type undefined 和the tsc issue
【解决方案2】:

不幸的是,我的调查最终发现,使用 TypesScript 是不可能做到这一点的。 以下链接解释了为什么做出这个不直观的决定

  1. Void type
  2. Assignability of functions
  3. FAQ

最接近所需功能的解决方案是

  1. 键入返回函数以返回未定义
function foo(): () => undefined { ... }
  1. 在tsconfig.json 中设置选项
"compilerOptions": {"noImplicitReturns": false}
  1. 从返回的函数显式返回
function foo(): () => undefined { 
    return () => { return; }
}

看起来有点难看,但现在我们可以定义一个肯定不会返回任何内容的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-28
    • 2023-01-28
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 2016-04-22
    • 2017-08-09
    相关资源
    最近更新 更多