You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

关于Kotlin Multiplatform中commonMain定义的接口能否暴露给JS/TS实现的技术咨询

关于Kotlin Multiplatform中commonMain定义的接口能否暴露给JS/TS实现的技术咨询

问题拆解与实际解决方案

结合你遇到的现象和KMP的JS导出机制,我来逐一解答你的核心问题:


1. 有没有办法让commonMain里的接口被TS实现?

当然可以,但不能直接在commonMain里用external或直接导出——毕竟external是平台专属修饰符,只能在jsMain这类平台源集里生效。这里推荐用KMP的expect/actual机制来实现,既保留commonMain的跨平台接口定义,又能给JS平台生成可被TS正常实现的干净接口:

具体操作步骤:

  • 第一步:在commonMain定义期望接口
    只定义接口的核心结构,不用加任何平台相关的注解或修饰符:

    // commonMain
    expect interface HiFromCommonMain {
        fun hiThorg(): String
    }
    
  • 第二步:在jsMain实现可导出的实际接口
    actual关键字对接commonMain的期望,同时加上external@JsExport(注意要启用ExperimentalJsExport注解):

    // jsMain
    @OptIn(ExperimentalJsExport::class)
    @JsExport
    external actual interface HiFromCommonMain {
        override fun hiThorg(): String
    }
    

这样处理后,生成的TS接口就不会有那个烦人的__doNotUseOrImplementIt标记,TS代码可以直接实现:

class TsHiImpl implements com.thorg.core.shared.sample.HiFromCommonMain {
    hiThorg(): string {
        return "Hello from TypeScript!";
    }
}

2. 是不是不该在TS里实现Kotlin定义的接口?

这不是绝对的禁令,但需要结合场景谨慎选择

适合在TS实现的场景:

  • 这个接口是JS平台专属的扩展逻辑,不需要在JVM、Native等其他KMP平台复用
  • 你能完全保证TS实现的行为和Kotlin接口的约定100%匹配(包括方法参数、返回值、异常处理逻辑等)

不推荐在TS实现的场景:

  • 接口是跨平台核心逻辑的一部分:如果其他平台有Kotlin实现,TS版本很容易出现行为不一致,导致跨平台业务逻辑出错
  • 接口包含Kotlin特有的特性:比如默认方法、委托属性、inline函数等,TS很难完全匹配这些特性的底层行为
  • 对版本兼容性要求极高:Kotlin 2.1这类新版本的JS导出机制可能在后续迭代中调整,TS实现的接口可能需要跟着频繁修改

补充解释你遇到的现象

  • 为什么jsMain里直接用external + @JsExport可以生效?因为jsMain是平台专属源集,external在这里是合法的,它会告诉Kotlin:这个接口的实现由JS侧提供,所以生成的TS接口是干净的,没有额外的类型校验标记。
  • 为什么commonMain里不加external会生成带特殊标记的TS接口?那是Kotlin的跨平台类型安全防护机制,用来防止TS随意实现跨平台接口——Kotlin默认假设跨平台接口的实现应该由Kotlin本身提供,以此保证多平台行为的一致性。

如果还有细节问题可以随时补充,我再帮你细化方案~

火山引擎 最新活动