如何在定位JavaScript时表示多种类型(联合类型)
我想要做的是使用一个泛型类型,可以是其他三种类型之一。
这是一个函数的例子:
fun <T> get(key: String) : T where T: String, T: Number, T: Boolean {}
上面的代码不起作用,那么我应该怎么做呢?
对于KotlinJS,您可以使用ts2kt将您的TypeScript定义转换为Kotlin。 它确实支持联盟类型,但也许不是所有的情况都是完美的。 在ts2kt中有对unionTypes的测试,这些测试揭示了如何处理它们,并且可以为定位JavaScript平台时手动创建的任何东西做类似的事情。
在第41期的评论中提到了进一步的工作- 增加更好的联盟类型支持 。 最后在主题上至少有一个讨论主题,表明:
在JS和TS中,在大多数情况下,union类型被用作重载的替代,所以在不久的将来,我们将在可能的时候使用重载。 另外,我们考虑提供额外的方式来为本地声明指定联合类型。
还有另一个堆栈溢出问题在谈论这个问题,并给出了一些当前的选择: Kotlin和歧视工会(总和类型) ,其中有答案是所有Kotlin目标平台有效。
特别是对于JavaScript目标,您可以考虑使用dynamic
类型 。 我在ts2kt中看到至少有一个使用这种类型的测试用例 。 这个例子从这个TypeScript代码开始:
declare class Foo type Key = Key2 | number; type Key2 = string | Foo; declare var fooKey: Key; declare function barKey(a: Key|number); declare function barList(a: List<Key>); declare function barArray(a: Key[]); interface Parent { (...children: Key[]): Foo; }
并使用dynamic
生成此Kotlin作为返回类型来代替联合类型; 在其他情况下重载方法签名来处理联合类型( 我添加了一些注释 ):
external open class Foo // using dynamic in place of union type external var fooKey: dynamic /* String | Foo | Number */ = definedExternally // using method overloading in place of union type external fun barKey(a: String): Unit = definedExternally external fun barKey(a: Foo): Unit = definedExternally external fun barKey(a: Number): Unit = definedExternally // using dynamic in place of union type external fun barList(a: List<dynamic /* String | Foo | Number */>): Unit = definedExternally external fun barArray(a: Array<dynamic /* String | Foo | Number */>): Unit = definedExternally external interface Parent { // using method overloading in place of union type @nativeInvoke fun invoke(vararg children: String): Foo @nativeInvoke fun invoke(vararg children: Foo): Foo @nativeInvoke fun invoke(vararg children: Number): Foo }
但是,您应该再次查看联合类型的所有ts2kt测试用例,以查看包括处理undefined
其他想法。
这是行不通的,因为T
不能表示为String
, Number
和Boolean
的交集。
如果你想限制你的类型到一个预定义的类型列表,密封类是一个很好的soltuion。
sealed class MyData { class Bool(val data: Boolean) : MyData() class String(val data: String) : MyData() class Number(val data: Number) : MyData() } fun get(key: String): MyData = TODO()
编译器如何知道在这种情况下返回哪种类型? T
可能是任何东西,所以他们将无法定义这样的东西。
你可以定义三种类型特定的方法:
fun getString(key: String): String = ... fun getBoolean(key: String): Boolean= ... fun getInt(key: String): Int = ...
(或者像kevinmost建议的封装方法)