Skip to main content

64-bit Integers

BrightScript distinguishes ordinary 32-bit integer variables from 64-bit long integers. A long variable or literal uses the & type designator. Hosanna exposes the branded TypeScript type:

import type { roLongInteger } from '@hs-src/hosanna-bridge-core/brs-api';

Use it for timestamps, counters, identifiers, and platform APIs whose valid integer range can exceed 2,147,483,647.

Annotate values and contracts

const startedAt = HsDate.now();
const explicit = 1775193886818 as roLongInteger;

interface ProgramWindow {
startSeconds: roLongInteger;
endSeconds: roLongInteger;
}

function addSeconds(
value: roLongInteger,
seconds: number
): roLongInteger {
return (value + seconds) as roLongInteger;
}

The compiler tracks the brand through declarations, inferred return types, parameters, class and interface fields, arrays, records, closures, assignments, and compound assignments. It emits & for BrightScript variable slots and uses long-integer conversion helpers for values stored in object properties. Object keys themselves remain ordinary strings.

Large literals

A numeric literal above Roku's signed 32-bit maximum is emitted as a long literal automatically, but the compiler reports it when the source did not make that intent explicit:

// Explicit intent; no ambiguous-large-literal warning
const argb = 4294967296 as roLongInteger;

Prefer the cast or a typed contract even when automatic literal conversion would produce the same BrightScript. It documents that the wider range is required and helps later assignments retain the correct variable type.

The brand does not give JavaScript arbitrary-precision integer semantics. On web and native JavaScript targets, values are still number; stay within the safe integer range when exact cross-platform representation matters.

Async limitation

The compiler cannot currently hoist a local roLongInteger variable into an async state machine. Compute long-integer values in a synchronous helper and pass or return the result:

function currentRunId(): roLongInteger {
return HsDate.now();
}

async function sendTelemetry(): Promise<void> {
await uploadRun(currentRunId());
}

If an async local must remain live across await, refactor the operation so the long value is produced or consumed on one side of the suspension. Do not remove the type merely to silence the diagnostic; that can change generated Roku semantics.

Practical checks

  • Type fields and function boundaries, not only individual literals.
  • Re-cast arithmetic results when the API contract remains a roLongInteger.
  • Use HsDate rather than JavaScript Date for portable millisecond values.
  • Inspect generated BrightScript when a long value passes through a complex object or closure.
  • Test values above 32-bit range on Roku and in the JavaScript targets.
Talk to us