KotlinJS + Typescript:在 d.ts 文件中找不到 Atomicfu TraceBase 参考

KotlinJS + Typescript: Atomicfu TraceBase reference not found in d.ts file

具有 coroutinektor 依赖项,当 KotlinJS npm 库发布时,在生成的打字稿 d.ts 文件中有 atomicfu 引用

export namespace kotlinx.atomicfu {
    function atomic$ref$<T>(initial: T, trace: kotlinx.atomicfu.TraceBase): kotlinx.atomicfu.AtomicRef<T>;
    function atomic$boolean$(initial: boolean, trace: kotlinx.atomicfu.TraceBase): kotlinx.atomicfu.AtomicBoolean;
    function atomic$int$(initial: number, trace: kotlinx.atomicfu.TraceBase): kotlinx.atomicfu.AtomicInt;
    function atomic$long$(initial: kotlin.Long, trace: kotlinx.atomicfu.TraceBase): kotlinx.atomicfu.AtomicLong;
}

但是文件中缺少对 TraceBase 的引用,并且在编译依赖于上述 kotlinJS 库的 Typescript 应用程序时,它抱怨缺少 TraceBase

前进的唯一方法是在 tsconfig 文件中添加 skipLibCheck = true。对于库的用户来说,这不是一个理想的解决方案。

有办法解决这个问题吗?

这是一个已知的编译器错误。创建了一个问题来修复它:https://youtrack.jetbrains.com/issue/KT-50464

暂时您可以使用 Gradle 解决它,方法是从生成的 d.ts 文件中删除所有 atomicfu 引用。

下面的解决方案假定您使用 this Gradle plugin NPM package publishing。它提供了一个 packJsNpmPublication 任务来构建 js 库发布代码,并为生成的文件指定特定的命名。

您应该添加以下两个 gradle 任务

// This task copies content of "js" build folder into a "temp" folder

tasks.register<Copy>("copyJsBuildContentToTemp") {
    this.from("$buildDir/publications/npm/js/")
    this.into("$buildDir/publications/npm/js/temp/")
}

// This task goes through your `d.ts` file from `temp` folder,
// Removes all the lines containing `atomicfu` word and then last line with '}'
// Then copies the modified file back into `js` folder that replaces the original file
// At the end, it deletes the `temp` folder

tasks.register<Copy>("removeAtomicFu") {
    var atomicfu = false
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
    from(buildDir.resolve("$buildDir/publications/npm/js/temp/${rootProject.name}-${project.name}.d.ts")) {
        filter {
            when {
                it.contains("atomicfu") -> {
                    atomicfu = true
                    ""
                }
                atomicfu && it == "}" -> {
                    atomicfu = false
                    ""
                }
                else -> it
            }
        }
    }
    this.into("$buildDir/publications/npm/js/")
    dependsOn("copyJsBuildContentToTemp")
    doLast {
        delete("$buildDir/publications/npm/js/temp")
    }
}

// This makes sure that `removeAtomicFu` tasks runs at the end of task 
// `assembleJsNpmPublication` so when `pack` or `publish` runs and creates 
// the `tarball` file, it would put update content in the `tgz` file
project.afterEvaluate {
    tasks.findByName("assembleJsNpmPublication")?.finalizedBy("removeAtomicFu")
}

现在,如果您 运行 ./gradlew packJsNpmPublication 您将拥有没有 atomicfu 引用的构建内容。