Numbers: u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, isize, usize, f32, and f64

T parameter &T parameter &mut T parameter T return value Option<T> parameter Option<T> return value JavaScript representation
Yes No No Yes Yes Yes A JavaScript number or bigint value

JavaScript Numbers are 64-bit floating point value under the hood and cannot accurately represent all of Rust's numeric types. wasm-bindgen will automatically use either BigInt or Number to accurately represent Rust's numeric types in JavaScript:

  • u8, i8, u16, i16, u32, i32, isize, usize, f32, and f64 will be represented as Number in JavaScript.
  • u64, i64, u128, and i128 will be represented as BigInt in JavaScript.

Note: Wasm is currently a 32-bit architecture, so isize and usize are 32-bit integers and "fit" into a JavaScript Number.

Note: u128 and i128 require wasm-bindgen version 0.2.96 or later.

Converting from JavaScript to Rust

wasm-bindgen will automatically handle the conversion of JavaScript numbers to Rust numeric types. The conversion rules are as follows:

Number to u8, i8, u16, i16, u32, i32, isize, and usize

If the JavaScript number is Infinity, -Infinity, or NaN, then the Rust value will be 0. Otherwise, the JavaScript number will rounded towards zero (see Math.trunc or f64::trunc). If the rounded number is too large or too small for the target integer type, it will wrap around.

For example, if the target type is i8, Rust will see the following values for the following inputs:

JS input number Rust value (i8)
42 42
-42 -42
1.999 1
-1.999 -1
127 127
128 -128
255 -1
256 0
-0 0
±Infinity 0
NaN 0

This is the same behavior as assigning the JavaScript Number to a typed array of the appropriate integer type in JavaScript, i.e. new Uint8Array([value])[0].

Except for the handling of Infinity and -Infinity, this is the same behavior as casting f64 to the appropriate integer type in Rust, i.e. value_f64 as u32.

BigInt to u64, i64, u128, and i128

If the JavaScript BigInt is too large or too small for the target integer type, it will wrap around.

This is the same behavior as assigning the JavaScript BigInt to a typed array for 64-bit integer types in JavaScript, i.e. new Int64Array([value])[0].

Number to f32

The JavaScript Number is converted to a Rust f32 using the same rules as casting f64 to f32 in Rust, i.e. value_f64 as f32.

This is the same behavior as Math.fround or assigning the JavaScript Number to a Float32Array in JavaScript, i.e. new Float32Array([value])[0].

Number to f64

Since JavaScript numbers are 64-bit floating point values, converting a JavaScript Number to a Rust f64 is a no-op.

Example Rust Usage


# #![allow(unused_variables)]
#fn main() {
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn take_number_by_value(x: u32) {}

#[wasm_bindgen]
pub fn return_number() -> f64 {
    42.0
}

#[wasm_bindgen]
pub fn take_option_number(x: Option<u8>) {}

#[wasm_bindgen]
pub fn return_option_number() -> Option<i16> {
    Some(-300)
}

#}

Example JavaScript Usage

import {
  take_number_by_value,
  return_number,
  take_option_number,
  return_option_number,
} from './guide_supported_types_examples';

take_number_by_value(42);

let x = return_number();
console.log(typeof x); // "number"

take_option_number(null);
take_option_number(undefined);
take_option_number(13);

let y = return_option_number();
if (y == null) {
  // ...
} else {
  console.log(typeof y); // "number"
}