TypeScript 版本: 3.4.0-dev.201xxxxx
搜索词:
代码
const w: void = "";
const x: () => void = () => "";
const y: () => Promise<void> = async () => "";
function a(): void {
return "";
}
async function b(): Promise<void> {
return "";
}
const y2: () => Promise<() => void> = async () => () => "";
function a2(): () => void {
return () => "";
}
function b2(): Promise<() => void> {
return () => "";
}
预期行为:
一般来说,它们都应该是错误,或者它们都不应该是。
实际行为:
我们有一个特殊的 "返回 void 的函数" 规则,允许 () => ""
可以赋值给 () => void
,但这并不适用于异步场景,所以一个 async () => ""
不能赋值给一个 () => Promise<void>
。
实验链接
6条答案
按热度按时间w1jd8yoj1#
我们有两条规则来管理上述内容:
undefined
的值。A function type whose return value is
voidis treated as though that
voidwere
unknown,用于可分配性。 这导致了一个令人讨厌的不一致性,即使带有注解返回
void的函数语句/表达式被检查为
undefined-ness,但被分配给具有函数类型注解的函数表达式的
const却不以相同的方式进行检查。另外,第二条规则在某些情况下无法影响异步函数,因为它们 *不*返回
void,而是返回
Promise` 。lb3vh1jj2#
这已经让我在为miniSphere编写类型时感到痛苦了。一般来说,我喜欢这样的规则:对于赋值目的,
void
返回的行为相当于any
,因为它在HOF场景(回调等)中很有用,而且我不能用异步函数获得相同的行为让我感到沮丧。z3yyvxxp3#
这似乎有点棘手:如果我们让
void
赋值规则适用于Promise<void>
,那么它是否会影响具有void
类型参数的任何泛型?我不确定这是否可取...即使是这样...当类型参数是协变的时候怎么办?或者不变?变化是否会影响它?这是一个相当大的难题。
mec1mxoz4#
实际上,我认为
void
只需要表现得像unknown
一样,除了我们还有lint级别的检查,试图禁止在预期返回位置类型为void
的实现中返回实值。nwwlzxa75#
我不知道,我觉得现在
void
和any
的二元性有点优雅。😃any
:随你所愿,我不打扰你,但运行时错误是你现在的问题void
:我会把任何东西放在这里,不要试图阻止我(通过检查值)否则yzckvree6#
我已经注意到,在以下情况下,void的行为并不符合预期:
这应该抛出一个错误,因为
() => () => void
不等于() => void
这个bug让我花了好几个小时试图弄清楚我做错了什么。
发现
() => () => {}
应该改为() => {}
并不容易,尤其是当你期望TS能检测到类似这样的类型冲突问题时。