KMM中泛型上限与typealias类型不兼容的编译错误求助
KMM泛型类型约束与typealias映射编译错误解决方案
问题根源
你遇到的编译错误本质是:用typealias直接映射CommonParcelable到Android的Parcelable时,编译器无法将别名后的类型与Common模块中声明的CommonParcelable接口视为同一类型边界,导致泛型约束检查失败。typealias只是类型的别名,并非实际的类型继承或实现关系,所以在泛型上限校验时,编译器会认为CommonParcelable /* = Parcelable */不符合原CommonParcelable的约束。
解决步骤
1. 保留Common模块的expect声明
// commonMain/kotlin/your/package/CommonParcelable.kt expect interface CommonParcelable expect annotation class CommonParcelize()
2. 修改Android模块的actual实现
将原来的typealias改为actual接口实现,让Android端的CommonParcelable继承自系统的Parcelable:
// androidMain/kotlin/your/package/CommonParcelable.kt actual interface CommonParcelable : android.os.Parcelable // 注解仍可使用typealias映射 actual typealias CommonParcelize = kotlinx.android.parcel.Parcelize
3. 验证泛型类使用
在Common模块定义的泛型类:
// commonMain/kotlin/your/package/Marker.kt class Marker<T : CommonParcelable>(val value: T)
此时在Android模块中声明:
val markers: List<Marker<CommonParcelable>> = listOf() // 或者传入实现了CommonParcelable的Event类 val eventMarker = Marker(Event()) // Event在Common模块标注@CommonParcelize并实现CommonParcelable
编译器会正确识别类型约束,编译通过。
原理说明
改用actual interface后,Android端的CommonParcelable是Common模块中expect接口的实际实现,同时继承了Android系统的Parcelable,既满足了Common模块的泛型约束,又具备Android端的Parcelable序列化能力。而typealias仅做类型别名替换,无法建立接口层面的继承关系,导致泛型约束校验不通过。
内容的提问来源于stack exchange,提问作者loic .B
相关产品推荐
相关产品推荐

