- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我刚刚成功地将 Kotlin 编译的 javascript 模块导入到 angular 6 typescript 文件中。这并不容易,结果让我感到困惑。我想知道是否存在更优雅的方式。
最初我拿了一个 Kotlin 文件:
package com.example.test
data class SomeInterface(
var id: String? = null,
var value: String? = null
) {
}
它可以很好地编译为以下 JavaScript
(function (root, factory) {
if (typeof define === 'function' && define.amd)
define(['exports', 'kotlin'], factory);
else if (typeof exports === 'object')
factory(module.exports, require('kotlin'));
else {
if (typeof kotlin === 'undefined') {
throw new Error("Error loading module 'TestKotlinCompiled'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'TestKotlinCompiled'.");
}
root.TestKotlinCompiled = factory(typeof TestKotlinCompiled === 'undefined' ? {} : TestKotlinCompiled, kotlin);
}
}(this, function (_, Kotlin) {
'use strict';
var Kind_CLASS = Kotlin.Kind.CLASS;
function SomeInterface(id, value) {
if (id === void 0)
id = null;
if (value === void 0)
value = null;
this.id = id;
this.value = value;
}
SomeInterface.$metadata$ = {
kind: Kind_CLASS,
simpleName: 'SomeInterface',
interfaces: []
};
SomeInterface.prototype.component1 = function () {
return this.id;
};
SomeInterface.prototype.component2 = function () {
return this.value;
};
SomeInterface.prototype.copy_rkkr90$ = function (id, value) {
return new SomeInterface(id === void 0 ? this.id : id, value === void 0 ? this.value : value);
};
SomeInterface.prototype.toString = function () {
return 'SomeInterface(id=' + Kotlin.toString(this.id) + (', value=' + Kotlin.toString(this.value)) + ')';
};
SomeInterface.prototype.hashCode = function () {
var result = 0;
result = result * 31 + Kotlin.hashCode(this.id) | 0;
result = result * 31 + Kotlin.hashCode(this.value) | 0;
return result;
};
SomeInterface.prototype.equals = function (other) {
return this === other || (other !== null && (typeof other === 'object' && (Object.getPrototypeOf(this) === Object.getPrototypeOf(other) && (Kotlin.equals(this.id, other.id) && Kotlin.equals(this.value, other.value)))));
};
var package$com = _.com || (_.com = {});
var package$example = package$com.example || (package$com.example = {});
var package$test = package$example.test || (package$example.test = {});
package$test.SomeInterface = SomeInterface;
Kotlin.defineModule('TestKotlinCompiled', _);
return _;
}));
在 package.json 中,我将 "kotlin": "^1.2.70",
添加到依赖项部分。在 Angular 组件中,我必须使用这样的代码进行导入。
import * as TestKotlinCompiled from "../../generated/TestKotlinCompiled";
// @ts-ignore
const SomeInterface = TestKotlinCompiled.com.example.test.SomeInterface;
// @ts-ignore
type SomeInterface = TestKotlinCompiled.com.example.test.SomeInterface;
这是使用生成到模块 TestKotlinCompiled
的包 com.example.test
中的类 SomeInterfac
的最少强制代码。
这里的问题如下。
//@ts-ignore
是必需的,因为在编译时 ts-comiler 看不到正在导入的模块的内容。
new SomeInterface()
需要
const
let x: SomeInterface;
type
所有这些看起来都非常老套。我想要一些更简单的东西,比如使用命名空间 com.example.test
从 '../../generated/TestKotlinCompiled' 导入 {SomeInterface},而不使用 const
和 type
。那么,有没有办法简化我上面的代码呢?
最佳答案
我成功地在 Angular 中提高了 KotlinJs 的一点点可用性。我在 https://github.com/svok/kotlin-multiplatform-sample 中处理我的实验
首先,我们必须在 Gradle 中创建一个多平台子模块。我们生成 js 文件(在其他可能的平台中)。
然后我们添加到 package.json...
{
"dependencies": {
"kotlin": "^1.3.21",
"proj-common": "file:../build/javascript-compiled"
}
}
proj-common 是我们编译的 Kotlin 模块。那里的路径是构建 kotlin-js 文件的位置。
因此,在 typescript 中我们只使用了一个 npm 模块
import {sample} from 'proj-common/proj-common';
// For class Sample
sample = new sample.Sample();
// For object Platform
platform = sample.Platform;
编译顺利,无需使用//@ts-ignore
在上面的解释中,子依赖存在问题。它们没有被导出,但并非所有子依赖项在 npm 存储库中都有它们的等价物。下面的代码解决了这个问题。
tasks {
task<Sync>("assembleWeb") {
val dependencies = configurations.get("jsMainImplementation").map {
val file = it
val (tDir, tVer) = "^(.*)-([\\d.]+-\\w+|[\\d.]+)\\.jar$"
.toRegex()
.find(file.name)
?.groupValues
?.drop(1)
?: listOf("", "")
var jsFile: File? = null
copy {
from(zipTree(file.absolutePath), {
includeEmptyDirs = false
include { fileTreeElement ->
val path = fileTreeElement.path
val res = (path.endsWith(".js") || path.endsWith(".map"))
&& (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/"))
if (res && path.endsWith(".js") && ! path.endsWith(".meta.js")) jsFile = fileTreeElement.file
res
}
})
into("$npmTarget/$tDir")
}
jsFile?.also { packageJson(tDir, it, tVer) }
tDir to jsFile
}
.filter { it.second != null }
.map { it.first to it.second!! }
.toMap()
packageJson(npmDir, File(jsOutputFile), project.version.toString(), dependencies)
dependsOn("jsMainClasses")
}
assemble.get().dependsOn("assembleWeb")
}
fun packageJson(dir: String, jsFile: File, version: String, dependencies: Map<String, File> = emptyMap()) {
val deps = dependencies.map {
""""${js2Name(it.value)}": "file:../${it.key}""""
}.joinToString(",\n ")
val text = """
{
"name": "${js2Name(jsFile)}",
"version": "${version}",
"main": "./${jsFile.name}",
"dependencies": {
${deps}
}
}
""".trimIndent()
File("$npmTarget/$dir/package.json").apply {
if (parentFile.exists()) {
parentFile.delete()
}
parentFile.mkdirs()
writeText(text)
}
}
fun js2Name(jsFile: File) = jsFile.name.replace("""\.js$""".toRegex(), "")
然后,从前面的子模块导入:
{
"dependencies": {
"proj-common": "file:../build/npm"
}
}
在 typescript 文件中:
import {sample} from 'proj-common';
// For class Sample
sample = new sample.Sample();
// For object Platform
platform = sample.Platform;
示例项目见 https://github.com/svok/kotlin-multiplatform-sample
现在您可以使用 kotlin 通用子项目创建全栈项目,就像在 gradle 中附加插件一样简单
plugins {
id("com.crowdproj.plugins.jar2npm")
}
这个插件会在编译过程中自动将你所有的 kotlin-js jar 包注入(inject)到你的 node_modules 中。
https://github.com/svok/kotlin-multiplatform-sample项目现在用这个插件重写。见 proj-angularfront子模块。
关于javascript - Angular 6 typescript 与 KotlinJs 的集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52529758/
我已经写了并且 npm 发布了这个:https://github.com/justin-calleja/pkg-dependents 现在我正在用 Typescript 编写这个包:https://g
我有一个函数,我想在 TypeScript 中模拟它以进行测试。在我的测试中,我只关心 json和 status .但是,当使用 Jest 的 jest.spyOn 时我的模拟函数的类型设置为返回 h
我正在使用一个库 (Axios),它的包中包含 Typescript 声明。 我想声明一个将 AxiosResponse(在库的 .d.ts 文件中声明)作为参数的函数。我有以下内容: functio
我是 Typescript 的新手。我想使用 将一个 Typescript 文件加载到另一个 Typescript 文件中标签。 我做了一些事情,但它不起作用!请帮助我。 first.ts: imp
为什么我会收到下面屏幕截图中显示的错误? Atom 说我的 tsconfig.json“项目文件包含无效选项”用于 allowJs、buildOnSave 和 compileOnSave。 但是应该允
所以我正在创建一个 TypeScript 库,我可以轻松地将所有生成的 JS 文件编译成一个文件。有没有办法将所有 .ts 和 .d.ts 编译成一个 .ts 文件? 除了支持 JS 的版本(较少的智
Microsoft Research 提供了一种名为Safer TypeScript 的新 TypeScript 编译器变体: http://research.microsoft.com/en-us/
我需要这个来在单个文件中分发 TypeScript 中的库。有没有办法将多个 typescript 文件合并到(一个js文件+一个 typescript 定义)文件中? 最佳答案 要创建一个库,您可以
用例:我想知道一个函数在 typescript 中执行需要多少时间。我想为此目的使用装饰器。我希望装饰器应该返回时间以便(我可以进一步使用它),而不仅仅是打印它。 例如: export functio
我想检查一个类型是否可以为 null,以及它是否具有值的条件类型。 我尝试实现 type IsNullable = T extends null ? true : false; 但是好像不行 type
我的问题是基于这个 question and answer 假设我们有下一个代码: const myFn = (p: { a: (n: number) => T, b: (o: T) => v
我知道双重否定前缀,我知道 TypeScript 的单后缀(非空断言)。 但是这个双后缀感叹号是什么? /.*验证码为(\d{6}).*/.exec(email.body!!)!![1] 取自here
我正在使用以下文件结构在 Webstorm 中开发一个项目 | src | ... | many files | types | SomeInterface |
在 TypeScript 类中,可以为属性声明类型,例如: class className { property: string; }; 如何在对象字面量中声明属性的类型? 我试过下面的代码,但它
我正在寻找一种在不丢失推断类型信息的情况下将 TypeScript 中的文字值限制为特定类型的好方法。 让我们考虑一个类型Named,它保证有一个名字。 type Named = { name:
在 TypeScript 中,我想创建一个联合类型来表示属于一个或多个不同类型的值,类似于 oneOf在 OpenAPI或 JSON Schema .根据a previous answer on a
type Func = (foo:string) => void // function expression const myFunctionExpression:Func = function(f
假设我有一个联合类型,我正在使用类似 reducer 的 API 调用模式,看起来像这样: type Action = { request: { action: "create
我在 typescript 中有以下去抖功能: export function debounce( callback: (...args: any[]) => void, wait: numb
在 Vue3 的 defineComponent 函数中,第一个泛型参数是 Props,所以我在这里使用 Typescript 接口(interface)提供我的 props 类型。喜欢: expor
我是一名优秀的程序员,十分优秀!