Skip to content

Triple equality and unexpected result on union types #1069

Closed
@mpapierski

Description

@mpapierski

Hello!

I'm learning AssemblyScript language and I stumbled upon very strange behavior of === identity operator when combined with upper case numeric types (i.e. U32) and null values.

It seems like a function that return values of type U32 | null which are tested with foo() === null returns true for both result == 0 and result == null;. It seems like its impossible to differentiate those two cases and x === null always returns true for x values of [0, null, <U32>null, <U32>0] etc.

Example:

I have a function that reads an U32 value from bytes of Uint8Array type. If length of those bytes is less than 4, then function returns null (byte stream is invalid), otherwise it returns load<u32> casted to U32 (byte stream contains a valid U32).

export function readU32(bytes: Uint8Array): U32 | null {
    if (bytes.length < 4) {
        return null;
    }
    const number = <u32>load<u32>(bytes.dataStart);
    return <U32>number;
}

Example usage that demonstrates the issue:

let bytes = new Uint8Array(4);
bytes.fill(0);
let result = readU32(bytes);
assert(result === null); // true
assert(result === <U32>0); // true

Expected behavior would be to make result === null a false when result contains zero value, but true if result is actually a null.

If the current behavior of === is intended, what would be the workaround to differentiate those two separate values?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions