在Typescript docs中,它说

void表示不返回值的函数的返回值.只要函数没有任何RETURN语句,或者没有从这些RETURN语句返回任何显式值,它就是推断类型.

void的作用很清楚,但我不明白为什么类型脚本编译器似乎不能推断出第一个代码块的返回类型为void,因为没有返回值或返回语句.

一百零二

function forEach<T>(arr: T[], callbackFn: (arg: T, idx: number) => undefined): void {
  for (let i = 0; i < arr.length; i++) {
    callbackFn(arr[i], i)
  }
}

// works
forEach([1, 2, 3], (arg, idx) => {
  console.log({arg, idx})
})

// error Type 'void' is not assignable to type 'undefined'
// here void is inferred
forEach([1, 2, 3], (arg, idx) => console.log({arg, idx}))

推荐答案

在5.1之前的每个版本的TypeScrip中,您的第一次调用也会是一个错误:

function foo(cb: () => undefined) { }
foo(() => { console.log() }); // ERROR in TS5.0 and below:
//  ~~~~~~~~~~~~~~~~~~~~~~~
// Argument of type '() => void' is not assignable to parameter of type '() => undefined'.
// Type 'void' is not assignable to type 'undefined'.

但TypeScrip5.1引入了对easier implicit returns for undefined-returning functions的支持.具体地说,"如果一个函数没有返回表达式,并且正被传递给某个需要返回undefined的函数,则TypeScrip会推断该函数的返回类型为undefined."这就是为什么它是有效的,至少如果你是在context,预期是undefined:

foo(() => { console.log() }); // okay in TS5.1+
// no return statement in the function body, 
// inferred as undefined to satisfy context

这就是问题的答案.


请注意,如果您不在这样的上下文中,相同的正文仍将被推断为返回void而不是undefined,这意味着看似等价的第一个调用的两步版本将失败,即使在TS5.1中也是如此:

const cb = () => { console.log() };
// const cb: () => void

foo(cb); // error!
//  ~~
// Argument of type '() => void' is not assignable to parameter of type '() => undefined'.
// Type 'void' is not assignable to type 'undefined'.

另请注意,第二个代码块在所有版本中都失败.Arrow functions with concise bodies Like () => expr隐式地return主体表达式,而那些block bodies Like () => { expr }只在主体中有return语句时返回值.

因此,() => { console.log() }不返回任何值,而() => console.log()返回console.log()计算的值.according to the TS library console.log()返回void,意思是"this function might return anything at all, so don't do anything with the return value".(是的,void很奇怪,见Why is undefined assignable to void?)

可能shouldundefined,因为我们知道这是它在运行时实际返回的内容,但它是void,所以这就是编译器所知道的全部.如果console.log()可能会被评为任何值,那么在需要undefined的地方它会被拒绝:

foo(() => console.log())
// -----> ~~~~~~~~~~~~~
// Type 'void' is not assignable to type 'undefined'.

Playground link to code

Typescript相关问答推荐

为什么从数组中删除一个值会删除打字错误?

在分配给类型的只读变量中维护const的类型

在实现自定义主题后,Angular 不会更新视图

类型脚本映射类型:从对象和字符串列表到键值对象

Fp-ts使用任务的最佳方法包装选项

常量类型参数回退类型

如何缩小函数的返回类型?

我可以使用typeof来强制执行某些字符串吗

类型脚本-处理值或返回值的函数

界面中数组中的混合类型导致打字错误

如何使用泛型函数参数定义类型脚本函数

我不明白使用打字脚本在模板中展开参考

map 未显示控制台未显示任何错误@reaction-google-map/api

如何扩展RxJS?

必需的输入()参数仍然发出&没有初始值设定项&q;错误

Route.ts文件中未导出HTTP方法

TypeScript:方法获胜';t接受较窄类型作为参数

为什么我会得到一个;并不是所有的代码路径都返回一个值0;switch 中的所有情况何时返回或抛出?(来自vsCode/TypeScript)

有没有一种简单的方法可以访问Keyboard Shortcuts JSON文件中列出的每个命令的显示名称(标题)?

const nav: typechecking = useNavigation() 和 const nav = useNavigation() 之间有什么区别?