Skip to content

Types

Zeus is a statically typed language. Every variable, parameter, and return value has a type known at compile time. For local variables, the type is usually inferred from the initializer — you only need to write it explicitly when it matters.

Primitive Types

Integer Types

Zeus provides signed and unsigned integers of various sizes:

TypeSizeRange
i88-bit-128 to 127
i1616-bit-32,768 to 32,767
i3232-bit-2.1B to 2.1B
i6464-bit-9.2×10¹⁸ to 9.2×10¹⁸
u88-bit0 to 255
u1616-bit0 to 65,535
u3232-bit0 to 4.2B
u6464-bit0 to 1.8×10¹⁹
let small = 127; // inferred: i32 (integer literals default to signed, ≥ i32)
let normal = 1000000; // inferred: i32
let big: i64 = 9223372036854775807; // explicit: value requires i64
let positive: u32 = 4000000000; // explicit: the literal fits u32, so it adopts u32

Floating-Point Types

TypeSizePrecision
f3232-bit~7 decimal digits
f6464-bit~15 decimal digits
let pi = 3.14159; // inferred: f64
let precise: f32 = 3.14159; // explicit: want f32 precision

Boolean Type

The boolean type has two values: true and false.

let isReady = true;
let hasError = false;

Void Type

void indicates a function returns no value. The annotation is optional — omitting the return type is equivalent to writing : void:

function logMessage() {
// No return statement needed
}
// Explicit : void means the same thing
function reset(): void {
// ...
}

Null

null represents the absence of a value for object types:

let p: Point = null;

Numeric Literals

Integer Literals

Zeus supports multiple number bases:

let decimal = 42;
let binary = 0b101010; // 42 in binary
let octal = 0o52; // 42 in octal
let hex = 0x2A; // 42 in hexadecimal

Use underscores for readability:

let million = 1_000_000;
let mask = 0b1111_0000;

Floating-Point Literals

let simple = 3.14;
let scientific = 6.022e23; // Scientific notation

Type Compatibility

Implicit Conversions

Zeus performs automatic widening conversions:

let small: i8 = 10;
let big: i32 = small; // OK: i8 → i32
let integer = 42;
let floating: f64 = integer; // OK: i32 → f64

Allowed implicit conversions:

  • Smaller integers → larger integers (e.g., i8i32)
  • Integers → floats (e.g., i32f64)
  • An integer literal → any integer type whose range holds its value (e.g. let b: u8 = 200)
  • null → any object type
  • stringu8[] (creates a copy)
  • A derived object → a base type (upcast, e.g. DogAnimal)

Type Errors

Narrowing a runtime value is not implicit — use as:

let big: i32 = 1000;
let small: i8 = big; // Error: use `big as i8`
let f: i32 = 2.0; // Error: floats never implicitly become ints — use `2` or `2.0 as i32`

Incompatible types cause errors:

let num: i32 = 42;
let flag: boolean = num; // Error: cannot convert i32 to boolean

Type Casting with as

When an implicit conversion isn’t allowed, as performs an explicit cast: value as Type.

Numeric and boolean casts

Numeric casts are unchecked and cost nothing at runtime — they truncate or wrap, exactly like Rust’s as, Go, or C. Float→int truncates toward zero.

let big: i32 = 300;
let small: u8 = big as u8; // 300 wraps to 44 (300 mod 256)
let pi: f64 = 3.9;
let n: i32 = pi as i32; // 3 (truncates toward zero)
let flag: i32 = true as i32; // 1
let on: boolean = 5 as boolean; // true (any non-zero → true)

Casting between unrelated types (e.g. "hi" as i32) is a compile-time error.

Object downcasts

as also narrows an object reference to a subclass. This is checked at runtime: if the object isn’t actually an instance of the target class, it throws a ClassCastException. Casting between classes in unrelated hierarchies is a compile-time error.

class Animal { public legs: i32; constructor(l: i32) { this.legs = l; } }
class Dog extends Animal {
public name: string;
constructor() { super(4); this.name = "Rex"; }
}
let a: Animal = new Dog(); // implicit upcast
let d: Dog = a as Dog; // downcast — runtime-checked, succeeds here
console.log(d.name); // "Rex"
let other: Animal = new Animal(2);
let bad: Dog = other as Dog; // throws ClassCastException (not a Dog)

Upcasts (a derived object → a base type) need no as and no runtime check — they happen implicitly.


Complex Types

Strings

The string type represents immutable UTF-8 text:

let greeting = "Hello, World!";
let emoji = "Zeus 🚀";

Strings can be implicitly converted to u8[] (mutable byte array) and vice versa:

let text: string = "Hello";
let bytes: u8[] = text; // Creates mutable copy
bytes[0] = 'h'; // Modify the copy
let modified: string = bytes; // Back to string

See Strings for more details.

Arrays

Arrays are declared with Type[] syntax:

let numbers: i32[] = new i32[];
let matrix: f64[][] = new f64[][]; // 2D array

See Arrays for more details.

Classes

Classes define custom object types:

class Rectangle {
public width: f64;
public height: f64;
}
let rect: Rectangle = new Rectangle();

See Classes for more details.

Function Types

Functions can be stored in variables:

function add(a: i32, b: i32): i32 {
return a + b;
}
let operation: function(i32, i32): i32 = add;

Type Checking

Zeus performs thorough type checking at compile time:

function process(value: i32): boolean {
return value > 0;
}
let result = process(42); // inferred: boolean
// let wrong: i32 = process(42); // Error: boolean not assignable to i32
// process("hello"); // Error: string not assignable to i32