If I call the constructor of the data class instea...
# javascript
n
If I call the constructor of the data class instead, my app works fine. It’s only calls to the copy function that fail in this way
k
Can you build without DCE?
I can be either bug in compiler (in this case it must be quite sophisticated) or you are trying to deserialize class from JSON and then copy it
n
No deserialisation
I’m calling the
copy
function within a lambda passed to the setState method of a React component.
I’ll try building without DCE
k
Ah, there is some issue with react state. AFAIR, it should be
external interface
n
Oh. ok. with `var`s?
Is there an example anywhere?
k
Yes
n
thanks
In JavaScript I usually write react apps with immutable props. Is there any way to have immutable props in kotlin-react?
k
There's a way, but you won't like it, it's verbose
n
Ok
k
BTW, there are no immutable properties in JavaScript
Or at least, there's no way to ensure immutability on compile time, since there's no type system
n
I know. But the app code doesn’t mutate anything, which makes following the flow of data much easier.
k
And if you want run-time immutability, you can call Object.freeze
n
And (when writing this in Kotlin) means I don’t have to worry about forgetting to initialise mutable props and state, and I don’t have to mark them as nullable.
k
Copy code
fun <T> freeze(o: T): T = js("Object.freeze(o)")
You can try something like this:
Copy code
external interface I {
    val x: Int
}
external fun foo(o: I)

foo(object : I {
    override val x = 23
})
But this will generate verbose JavaScript with anonymous class on each call site
Also, this allows to declare optional properties like this:
Copy code
external interface I {
    val x: Int  // required
    val y: String? = definedExternally  // optional
}
n
That is nice
k
And there's no
copy
method 😞
Ah, I invented the way to provide copy semantics. Here's the example:
Copy code
val orig = object : I {
        override val x = 23
        
        override val y = 42
    }
    foo(object : I by orig {
        override val x = 99
    })
n
👍 cunning!
Using an external interface instead of a data class fixed everything and also stopped the app being janky and occasionally freezing the browser window for seconds at a time. I have no idea what was going on there!