given a type union of either an object or an array, how can I check (in Kotlin) whether I can cast a...
a
given a type union of either an object or an array, how can I check (in Kotlin) whether I can cast a property to an array or object?
Copy code
export type Extension = {extension: Extension} | readonly Extension[]

interface EditorStateConfig {
    extensions?: Extension;
}
j
is Array<*>
should work
a
thanks! I’ll give it a go.
I wasn’t sure about the best way because all the JavaScript guides say ‘use `Array.isArray()`’ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray, but I couldn’t find any usage of that with Kotlin/JS
@turansky hi 👋 Perhaps
Array.isArray()
should be added to JsArray, or would that be redundant and equivalent to
is Array<*>
?
t
is Array<*>
is preferable, equivalent isn’t required
Current plan for
JsArray
- use it internally only for public extensions like this:
Copy code
// not implemented now
fun JsIterator<T>.toTypedArray(): ReadonlyArray<T> = 
    JsArray.from(this)
About initial question
Copy code
export type Extension = {extension: Extension} | readonly Extension[]

{extension: Extension} - looks like fine TS/JS sugar
readonly Extension[]   - looks like what you will use in Kotlin
In Kotlin Wrappers we leave Kotlin signatures only if they used as input values (your case?)
a
cool, thanks for the answer. If I think a bit more about it, it makes sense, because
JsArray.isArray()
isn’t easily able to infer types:
Copy code
fun foo(arg: Any) {
  if (JsArray.isArray(arg)) {
    arg.size // ERROR: Unresolved reference: size
  }
  if (arg is Array<*>) {
    arg.size // ✓ type is inferred correctly
  }
}
but maybe adding
JsArray.isArray()
, but marking it as
@Deprecated
& with
ReplaceWith()
would help converting JS/TS code to Kotlin, and help developers to learn Kotlin?
Copy code
@Deprecated("Using an `is Array<*>` typecheck is preferred", ReplaceWith("value is Array<*>"))
inline fun JsArray.Companion.isArray(value: dynamic): Boolean = value is Array<*>
In Kotlin Wrappers we leave Kotlin signatures only if they used as input values (your case?)
Hmm I’m not sure I follow. Do you mean that I should only write Kotlin wrappers to handle the
readonly Extension[]
part of the union, because it’s more general, and the other part
{extension: Extension}
most likely won’t be used directly? Ignoring part of the type union certainly would make the code simpler, and help with writing wrappers.
t
To support
{extension: Extension}
you will need marker interface, which you probably won’t do 🙂
s
is Array<*>
is preferable, equivalent isn’t required
I totally disagree with it,
JsArray.isArray()
is essential check, we just need to support Kotlin contract for it to provide smart cast.
I checked it Kotlin playground, it is already converts is
Array<*>
to
Array.isArray()