for sure :), was stuck with this problem for provi...
# javascript
s
for sure :), was stuck with this problem for providing common types in a library on all 3 targets (js, ios, android) And KMP messes it up for Long types in JS, as generated code and .d.ts mapped it to
any
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)
t
In
2.2.20
problem will be solved on compiler level
s
Until then is this a decent way to get around it or if you know others? My usecase only cares about upto 64bit signed integers not arbitrary precision like biginteger