letIntOrNull function

int? letIntOrNull(
  1. dynamic input
)

Converts input to int, returning Null on failure.

Returns Null for NaN, Infinity, -Infinity, and any value whose integer representation would lose precision or saturate on the current runtime. Calling num.toInt() on out-of-range doubles would throw UnsupportedError or silently clamp to int64.min / int64.max — both unacceptable for life-critical code.

Cross-runtime safety. The accepted range adapts to the runtime:

  • On the Dart VM, int is a true 64-bit integer, so values in [-2^63, 2^63) round-trip exactly.
  • On the JS runtime (Flutter web / dart2js / dartdevc), int is backed by a 64-bit double, so only [-2^53, 2^53] is exact. Values outside that band have already lost precision by the time we see them, so letIntOrNull returns null rather than handing back a silently-rounded value.

Supported input types:

Implementation

int? letIntOrNull(dynamic input) {
  final n = letNumOrNull(input);
  if (n == null) return null;
  if (n is int) {
    // On JS, an `n is int` value past 2^53 may have already lost precision
    // during parsing — refuse it for life-critical use.
    if (isJsRuntime && (n > 9007199254740992 || n < -9007199254740992)) {
      return null;
    }
    return n;
  }
  final d = n.toDouble();
  if (!d.isFinite) return null;
  if (isJsRuntime) {
    if (d > jsSafeIntegerBound || d < -jsSafeIntegerBound) return null;
  } else {
    // VM: 2^63 itself is *not* in int64 (max is 2^63 - 1), but -2^63 *is*.
    if (d >= vmInt64Bound || d < -vmInt64Bound) return null;
  }
  return d.toInt();
}