kotlinkotlin-js

why doesn't "is" operator honor inheritance in kotlinjs


I'm developing a kotlinjs react project.

plugins {
    kotlin("js") version "1.8.0"
}

and I've written this class:

class Percentage(private val number: Number) : Number() {
    override fun toByte() = number.toByte()
    override fun toChar() = number.toChar()
    override fun toDouble() = number.toDouble()
    override fun toFloat() = number.toFloat()
    override fun toInt() = number.toInt()
    override fun toLong() = number.toLong()
    override fun toShort() = number.toShort()
    override fun toString() = "$number%"
}

but is operator seems not to honor inheritance:

if (value is Percentage) {
    println(value is Number)
}

even IDEA warns me that "check for instance is always true" yet console prints false...


Solution

  • So I check the generated JS code, and see this:

      function isNumber(a_28) {
        var tmp_349;
        if (typeof a_28 === 'number') {
          tmp_349 = true;
        } else {
          tmp_349 = a_28 instanceof Long;
        }
        return tmp_349;
      }
    
      function main() {
        var value_70 = new Percentage(42);
        if (value_70 instanceof Percentage) {
          println(isNumber(value_70));
        }
      }
    

    which explains everything. The is operator behavior is inconsistent around primitive type like Number, because of Kotlin/JS language difference.