如何在Kotlin中为属性的支持字段设置JsName?

Hug*_*ghG 6 kotlin kotlin-js-interop

我在1.0.x中使用了Kotlin不受支持的JavaScript后端,现在我正在尝试将我的玩具项目迁移到1.1.x. 它是与PouchDB连接的单页Web应用程序的最基本骨骼.要添加到PouchDB你需要具有特殊性能的JavaScript对象数据_id_rev.他们还需要没有任何其他属性,_因为它们是由PouchDB保留的.

现在,如果我创建这样的类,我可以将实例发送到PouchDB.

class PouchDoc(
        var _id: String
) {
    var _rev: String? = null
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我做任何事情来使属性成为虚拟 - 让它们覆盖一个接口,或者让类打开并创建一个覆盖它们的子类 - _id字段名称会变成类似的东西_id_mmz446$_0,因此PouchDB会拒绝该对象.如果我应用于@JsName("_id")属性,那只会影响生成的getter和setter - 它仍然会在后备字段中留下一个受损的名称.

此外,对于名称不以其开头的任何虚拟属性_,PouchDB将接受该对象,但它仅存储带有损坏名称的支持字段,而不是名称很好的属性.

我认为现在我可以通过使它们不虚拟来解决问题.但我想在Kotlin中分享PouchDoc和非PouchDoc类之间的接口,似乎我做不到.

知道我怎么能做这个工作,还是需要Kotlin语言改变呢?

bas*_*hor 3

我认为您的问题应该由 https://youtrack.jetbrains.com/issue/KT-8127涵盖

另外,我还创建了一些其他相关问题: https: //youtrack.jetbrains.com/issue/KT-17682 https://youtrack.jetbrains.com/issue/KT-17683

现在您可以使用下一个解决方案之一,IMO 第三个是最轻量级的。

interface PouchDoc1 {
    var id: String
    var _id: String
        get() = id
        set(v) { id = v}

    var rev: String?
    var _rev: String?
        get() = rev
        set(v) { rev = v}
}

class Impl1 : PouchDoc1 {
    override var id = "id0"
    override var rev: String? = "rev0"
}

interface PouchDoc2 {
    var id: String 
        get() = this.asDynamic()["_id"]
        set(v) { this.asDynamic()["_id"] = v}

    var rev: String?
        get() = this.asDynamic()["_rev"]
        set(v) { this.asDynamic()["_rev"] = v}
}

class Impl2 : PouchDoc2 {
    init {
        id = "id1"
        rev = "rev1"
    }
}

external interface PouchDoc3 { // marker interface 
}

var PouchDoc3.id: String 
    get() = this.asDynamic()["_id"]
    set(v) { this.asDynamic()["_id"] = v}

var PouchDoc3.rev: String?
    get() = this.asDynamic()["_rev"]
    set(v) { this.asDynamic()["_rev"] = v}

class Impl3 : PouchDoc3 {
    init {
        id = "id1"
        rev = "rev1"
    }
}

fun keys(a: Any) = js("Object").getOwnPropertyNames(a)

fun printKeys(a: Any) {
    println(a::class.simpleName)
    println(" instance keys: " + keys(a).toString())
    println("__proto__ keys: " + keys(a.asDynamic().__proto__).toString())
    println()
}

fun main(args: Array<String>) {
    printKeys(Impl1())
    printKeys(Impl2())
    printKeys(Impl3())
}
Run Code Online (Sandbox Code Playgroud)