我遇到了这种(对我来说)奇怪的行为,我不知道是否有充分的理由这样做,因为它对我来说没有意义.

在打印脚本中,如果我执行以下操作,它可以正常工作

type UndefinedFunction = () => undefined;

let uf: UndefinedFunction = function() {
    return; // no errors,
}

这对我来说是有意义的,就像在Java脚本中一样,当一个函数在没有值的情况下执行return;时,那么返回的值是undefined.

但如果我执行以下操作

type MaybeUndefinedFunction = () => string | undefined;

let muf: MaybeUndefinedFunction = function() {
    return; // error
}

然后我得到错误Type '() => void' is not assignable to type 'maybeUndefinedFunction'. Type 'void' is not assignable to type 'string | undefined'

这对我来说没有任何意义.我读了here本关于"空"与"未定义"的书,但它说"空"是一种表明答案不会被观察到的方式.但是,为什么现在return;被标识为void而不是undefined,如果在预览示例中它运行得很好呢?

如果我做return undefined;,错误就会消失,但我想知道,如果return;return undefined;产生相同的结果,为什么这是必要的.

顺便说一句,如果我根本不返回任何东西,也会发生同样的情况;在第一个事件上有效,但在第二个事件上不起作用,尽管这两个事件都应该符合undefined的返回值.

这里是一个playground ,让您看到实际操作中的错误:https://www.typescriptlang.org/play?#code/FAFwngDgpgBAqgOwCZQGYEsFSQMQK4IDGI6A9gjALwwAUAlFQHwwEoZZIDcwoksAsgEMwAIyiI2mbPiIlyVWg0rMAziABOmAOYwAPi2RopXHgBsoIFqgBc8Q+2kFiZCtVRO5CejADewGAEw6hZ46gjcAL5mFjAAtng2MEKi4vbGMs7ybh4u3n6BQSFhkTxAA

推荐答案

从历史上看,TypeScrip会将不返 echo 式值的函数视为a void return type,这意味着"没有人知道这个函数返回什么",而不是"这个函数返回undefined".在TypeScrip 5.1引入microsoft/TypeScript#53607中实现的easier implicit returns for undefined-returning functions之前,您的两个示例都会导致错误:

let uf: UndefinedFunction = function () { return; } // error!
//  ~~ <-- Type '() => void' is not assignable to type 'UndefinedFunction'.

Playground link to code in TS 5.0.4

但现在,uf不是错误的,因为根据前面的拉取请求:

  • 具有显式指定的返回类型undefined的函数不需要具有Return语句(类似于具有显式指定的返回类型voidany的函数).Note that this does not apply to functions with union return types that include 100[增加了重点].

但正如您所看到的,这只适用于返回类型仅为undefined的函数,而不适用于包含undefined的函数,例如string | undefined.因此,muf仍然有一个错误:

let muf: MaybeUndefinedFunction = function () { return; }
//  ~~~ <-- Type '() => void' is not assignable to type 'MaybeUndefinedFunction'.

这就是所问问题的答案.当然,人们可能会合理地问why个联合类型不受支持,事实上,有comment on microsoft/TypeScript#53607个目前没有回答这个问题.但目前还不清楚.大概只支持undefined是一件容易实现和保守的事情,也许他们会服从要求扩展它的后续功能请求?但从技术上讲,这超出了这个问题的范围.您展示的两个 case 是不同的,因为这就是微软/TypeScrip#53607的实现方式.

Typescript相关问答推荐

Typescript:将内部函数参数推断为子对象键的类型

有没有办法适当缩小类型?

带有微前端的动态React路由问题

SortKey类型不起作用,尽管它使用的单个类型工作正常<>'

数组文字中对象的从键开始枚举

输入元素是类型变体的对象数组的正确方法是什么?'

如何使函数接受类型脚本中具有正确类型的链接修饰符数组

从子类构造函数推断父类泛型类型

Angular 15使用react 式表单在数组内部创建动态表单数组

扩展参数必须具有元组类型或传递给REST参数

Angular:ngx-echart 5.2.2与Angular 9集成错误:NG 8002:无法绑定到选项,因为它不是div的已知属性'

笛卡尔产品类型

使用动态输出类型和泛型可重用接口提取对象属性

如何获取受类型脚本泛型约束的有效输入参数

在打字脚本中对可迭代对象进行可变压缩

如何避免多个类型参数重复?

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

递归类型别名的Typescript 使用

是否可以将类型参数约束为不具有属性?

在类型{}上找不到带有string类型参数的索引签名 - TypeScript