Kotlin/JS互操作中返回dynamic的lambda异常行为相关疑问
Kotlin/JS lambda返回dynamic类型问题解答
为什么() -> Unit默认无法转换为() -> dynamic
Kotlin/JS中dynamic是可以兼容所有JavaScript值的特殊类型,Unit对应JS的undefined,本身是可以赋值给dynamic的。你遇到的转换限制本质是Kotlin lambda隐式返回规则的场景差异:只有当lambda的最后一个表达式为普通Unit返回值的非赋值表达式时,编译器才允许隐式将() -> Unit适配为() -> dynamic。
为什么f校验失败、f2校验可以通过
两个lambda移除类型注解后推导类型都是() -> Unit,编译器对两者的适配逻辑不同:
- f的lambda最后一行是赋值表达式
a = 42,Kotlin规范明确赋值表达式的返回值固定为Unit,且为了避免赋值操作的返回值被意外使用,这种场景下编译器禁止隐式将() -> Unit适配为其他返回值的函数类型,包括() -> dynamic。 - f2的lambda最后一行是普通函数调用
print("foo"),属于非赋值的Unit返回表达式,编译器允许Unit到dynamic的隐式转换,因此可以通过类型校验。
最优实现方案
除了你目前用的末尾加null的写法,更规范的两种实现如下:
- 末尾加
Unit显式标记返回值,可读性最高:
var a: Int? val f: () -> dynamic = { a = 42 Unit }
- 显式做强转适配,无需额外加代码行,无运行时开销:
var a: Int? val f = { a = 42 } as () -> dynamic
两种写法都可以完美适配XMLHttpRequest.onreadystatechange的类型要求。
内容的提问来源于stack exchange,提问作者lsparki
相关产品推荐
相关产品推荐

