在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?)
可能should是undefined
,因为我们知道这是它在运行时实际返回的内容,但它是void
,所以这就是编译器所知道的全部.如果console.log()
可能会被评为任何值,那么在需要undefined
的地方它会被拒绝:
foo(() => console.log())
// -----> ~~~~~~~~~~~~~
// Type 'void' is not assignable to type 'undefined'.
Playground link to code个