Kotlin/JS 外部声明 - "Name contains illegal chars that can't appear in JavaScript identifier"
Kotlin/JS external declaration - "Name contains illegal chars that can't appear in JavaScript identifier"
编辑:尚不支持,tracked on Kotlin YouTrack
我正在尝试编写与以下 Typescript 接口匹配的 Kotlin external
声明(这是表示通过 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`
如果编译为 const length = headers["content-length"]
可能有效。
我尝试使用 @JsName
通过以下方式解决它:
@JsName("content-length")
@JsName("'content-length'")
@JsName("\"content-length\"")
但是所有这些都失败了,因为它们只允许作为有效 JS 标识符的字符串。
有办法解决这个问题吗?
问题是连字符 -
不是 Javascript 中的有效标识符。这意味着您不能像这样声明变量:
var content-length = 4
您只能这样做:var contentLength = 4
Kotlin Kultiplatform 不允许您编写无法编译到目标平台的通用代码,这就是为什么即使这是有效的 Kotlin 代码:
var `content-length`: String? // ...
由于 Javascript 限制,您仍然不能在多平台环境中使用它。
另请注意,虽然这可能是有效的 Typescript 代码,但 Kotlin 没有 Typescript 目标,只有 Javascript 一个,所以请记住这一点.
JSON 中允许使用连字符,我相信如果您使用刻度 (``),JavaScript 中也可能允许使用连字符。我在使用 jsObject 时遇到了同样的连字符问题,这就是字面意义上的解决方案。
我的连字符问题和这个解决方案:
pluginsOpts = jsObject<dynamic> {
this["grapesjs-tabs"] = jsObject<dynamic> {
tabsBlock = jsObject<dynamic> {
category = "Extra"
}
}
}
试试这个,从字面上看:
export interface Headers {
this['content-length']?: string;
}
我无法让它在外部工作,但这是一个很好的连字符 hack,可能会有帮助。以下是您将如何使用它:与其定义外部对象,不如在它所在的位置使用 jsObject{}。您可以嵌套它们,但一定要在每一层中明确包含动态标识符,尤其是当您必须在不同层中使用多个 this(es) 来克服连字符问题时。这是您的解决方案:
val Header = jsObject<dynamic> {
this["content-length"] = "something"
}
让“这个”成为你的一个教训。
我建议通过在 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
}
编辑:尚不支持,tracked on Kotlin YouTrack
我正在尝试编写与以下 Typescript 接口匹配的 Kotlin external
声明(这是表示通过 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`
如果编译为 const length = headers["content-length"]
可能有效。
我尝试使用 @JsName
通过以下方式解决它:
@JsName("content-length")
@JsName("'content-length'")
@JsName("\"content-length\"")
但是所有这些都失败了,因为它们只允许作为有效 JS 标识符的字符串。 有办法解决这个问题吗?
问题是连字符 -
不是 Javascript 中的有效标识符。这意味着您不能像这样声明变量:
var content-length = 4
您只能这样做:var contentLength = 4
Kotlin Kultiplatform 不允许您编写无法编译到目标平台的通用代码,这就是为什么即使这是有效的 Kotlin 代码:
var `content-length`: String? // ...
由于 Javascript 限制,您仍然不能在多平台环境中使用它。
另请注意,虽然这可能是有效的 Typescript 代码,但 Kotlin 没有 Typescript 目标,只有 Javascript 一个,所以请记住这一点.
JSON 中允许使用连字符,我相信如果您使用刻度 (``),JavaScript 中也可能允许使用连字符。我在使用 jsObject 时遇到了同样的连字符问题,这就是字面意义上的解决方案。
我的连字符问题和这个解决方案:
pluginsOpts = jsObject<dynamic> {
this["grapesjs-tabs"] = jsObject<dynamic> {
tabsBlock = jsObject<dynamic> {
category = "Extra"
}
}
}
试试这个,从字面上看:
export interface Headers {
this['content-length']?: string;
}
我无法让它在外部工作,但这是一个很好的连字符 hack,可能会有帮助。以下是您将如何使用它:与其定义外部对象,不如在它所在的位置使用 jsObject{}。您可以嵌套它们,但一定要在每一层中明确包含动态标识符,尤其是当您必须在不同层中使用多个 this(es) 来克服连字符问题时。这是您的解决方案:
val Header = jsObject<dynamic> {
this["content-length"] = "something"
}
让“这个”成为你的一个教训。
我建议通过在 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
}