ballerinatype-equivalence

How to correctly compare the types of two variables in Ballerina and ensure they have the same type?


I'm working with Ballerina and attempting to compare the types of two variables to ensure they have the same type. The code snippet looks like this:

typedesc type1 = typeof input1;
typedesc type2 = typeof input2;  
if type1 == type2 {
   //...
}

The == operator for type checks doesn't work as expected. I can use type1.toString() == type2.toString() but it does not work with union types and immutable records.


Solution

  • The typedesc equality can be checked using exact (reference) equality operator (===/!==) as follows. But, this and the toString() approach won't work with immutable values.

    import ballerina/io;
    
    type Foo record {|
        int a;
    |};
    
    type Bar record {|
        int a;
    |};
    
    public function main() {
        Foo foo1 = {a: 1};
        Foo foo2 = {a: 1};
        Bar bar = {a: 1};
        io:println(typeof foo1 === typeof foo2); // true  
        io:println(typeof foo1 === typeof bar); // false
    }
    

    Also, types of the variables can be checked separately using the is operator. As a workaround, the following method can be used for the comparison of types. However, if there are two similar immutable type variables (except for the simple types) which have different values for the fields, the types can be unequal.

    import ballerina/io;
    
    type Foo record {|
        int a;
    |};
    
    type Bar record {|
        int a;
    |};
    
    function getType(any value) returns string|error {
        if value is () {
            return "nil";
        } else if value is int {
            return "int";
        } else if value is float {
            return "float";
        } else if value is decimal {
            return "decimal";
        } else if value is boolean {
            return "boolean";
        } else if value is string {
            return "string";
        } else {
            var result = typeof value;
            if (result is typedesc) {
                string typeString = result.toString();
                return typeString.startsWith("typedesc ") ? typeString.substring(9) : typeString;
            } else {
                return result;
            }
        }
    }
    
    public function main() returns error? {
        Foo & readonly foo1 = {a: 1};
        Foo & readonly foo2 = {a: 1};
        Bar bar = {a: 1};
        io:println(check getType(foo1) == check getType(foo2)); // true  
        io:println(check getType(foo1) == check getType(bar)); // false
    }