我正在尝试编写一个与以下打字稿接口匹配的外部声明(这是表示通过headers['content-length']
进行JavaScript访问的有效TS):
export interface Headers {
'content-length'?: string;
}
Dukat生成以下内容,应将其视为有效:
external interface Headers {
var `content-length`: String? get() = definedExternally; set(value) = definedExternally
}
但是现在编译器抱怨:
Name contains illegal chars that can't appear in JavaScript identifier
的确,它不能出现在JS标识符中,但不是必须的。所有Kotlin都可以访问此属性,例如:
val length = headers.`content-length`
如果编译为let length = headers["content-length"]
,可能是有效的。
我尝试使用@JsName
通过以下方式解决该问题:
@JsName("content-length")
@JsName("'content-length'")
@JsName("\"content-length\"")
但是所有这些都失败了,因为它们将字符串限制为有效的标识符。 有办法解决这个问题吗?
编辑:我打开了一个issue on Kotlin YouTrack
答案 0 :(得分:1)
问题在于连字符-
在 Javascript 中不是有效的标识符。这意味着您不能声明这样的变量:
var content-length = 4
您只能执行以下操作:var contentLength = 4
Kotlin Kultiplatform不允许您编写无法编译为目标平台的通用代码,这就是即使这是有效的Kotlin代码的原因:
var `content-length`: String? // ...
由于 JavaScript 的限制,您仍然不能在多平台环境中使用它。
请注意,尽管这可能是有效的 Typescript 代码,但Kotlin没有Typescript目标,只有Javascript目标,因此请记住这一点。
答案 1 :(得分:1)
我建议通过在 Kotlin 中定义一个空接口来代表此类对象来解决这个问题,并加上一个扩展属性来获取和设置值:
external interface KHeader // stands in for JavaScript objects with content-length property
var KHeader.contentLength: String
get() = this.asDynamic()["content-length"]
set(value) { this.asDynamic()["content-length"] = value }
通过这种方式,您可以在 Kotlin 中使用 Header
JavaScript 对象与驼峰式大小写(参见 playground):
fun main() {
val jsObject = js("{}")
jsObject["content-length"] = "44"
val randomHeader = jsObject as KHeader
println(randomHeader.contentLength) // prints 44
randomHeader.contentLength = "55"
println(randomHeader.contentLength) // prints 55
}
答案 2 :(得分:0)
在JSON中允许使用连字符,如果您使用刻度(``),我相信在JavaScript中可以使用连字符。在使用jsObject时,我遇到了相同的连字符问题,从字面上看,这就是解决方案。
我的连字符问题和此解决方案:
pluginsOpts = jsObject<dynamic> {
this["grapesjs-tabs"] = jsObject<dynamic> {
tabsBlock = jsObject<dynamic> {
category = "Extra"
}
}
}
从字面上尝试:
export interface Headers {
this['content-length']?: string;
}
我无法在外部使用此功能,但这是一个很好的连字符破解,可能会有所帮助。使用方法如下:与其定义一个外部对象,不如使用一个jsObject {}。您可以嵌套它们,但一定要在每层中明确包含动态标识符,尤其是如果必须在不同层中使用多个this来克服连字符问题时。这是您的解决方案:
val Header = jsObject<dynamic> {
this["content-length"] = "something"
}
让“这”成为您的课程。