shikhar
07/16/2025, 4:03 PMany
type
solved it like below:
// common
expect class NativeLong
expect fun toNativeLong(value: Long): NativeLong
actual fun toKtLong(value: NativeLong): Long
// js
actual typealias NativeLong = BigInt
actual fun toNativeLong(value: Long) = (js("BigInt") as (dynamic) -> BigInt)(value.toString())
actual fun toKtLong(value: NativeLong) = value.toString().toLong() // throws if out-of-range
// ios/android
actual typealias NativeLong = Long
actual fun toNativeLong(value: Long): NativeLong = value
actual fun toKtLong(value: NativeLong): Long = value
And if it’s used in a @Serializable
class, we provide a custom serializer based on target platform
Now I can use it as:
data class UserId(id: NativeLong)
fun takeInput(value: NativeLong)
And its easily usable for js devs
// generated .d.ts
export declare class UserId {
constructor(id: BigInt);
get id(): BigInt;
copy(id?: BigInt): UserId;
toString(): string;
hashCode(): number;
equals(other: Nullable<any>): boolean;
}
export declare function takeInput(num: BigInt): void;
The primary downside here is overhead of toKtLong()
in js, which decodes->encodes the value on every call.
Solvable using a “holder” type for native values, which has a lazy prop that holds the kotlin long value.
For folks who have tackled this, please suggest your methods and any issues you see with above. (like if using typealiasing like this has any risks for exported types etc)turansky
07/16/2025, 5:28 PM2.2.20
problem will be solved on compiler levelshikhar
07/16/2025, 5:41 PM