Description
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?