menu
Primitives
Number, int32, uint32, int64, float32, character too.
Primitives
number, yes, but int32, uint32, int64, float32, character too
no real symbol use case left, so no
symbolorunique symbolstring and bigint are just regular classes (String, BigInt)
variable sized integers
isize / usize
(sequence collections default to isize instead of number)
keep null and undefined, no strong reason not to
keep freshness and widening
keep literal freshness
const / as const
integer overflow / underflow traps in all build models
explicit wrapping / saturating / checked arithmetic
only upcasts are allowed via
as
1const enabled: boolean = true;2const count: uint32 = 42;3const ratio: float64 = 0.75;4const initial: char = 'D';5const name: string = "Destack";Conversions
Conversions follow the same explicitness rule as the rest of Destack: as between numeric types is allowed only when every value of the source type is representable in the destination (lossless), and lossy conversions must pick their behavior explicitly:
1declare const wide: int32;2 3const a: int64 = wide as int64; // OK: lossless widening4const b: uint8 = wide as uint8; // ERROR: lossy conversion5const c = wide.truncate<uint8>(); // explicit: keep the low bits6const d = wide.saturate<uint8>(); // explicit: clamp into rangeIntervals
Ranges in type position become an interval type over bounded sets like int, bigint, or char; basically, an interval type is a static subset of its scalar type (e.g., 1..4 in type position is equivalent to 1 | 2 | 3).
Assignments to interval-typed places must already have an interval-compatible type - the compiler does not prove arithmetic expressions stay inside intervals and we do not insert implicit runtime checks for interval assignments.
1type Digit = 0..=9;2type LowerAscii = 'a'..='z';3type UserPort = 1024..=65535;4 5let digit: Digit = 7;6let letter: LowerAscii = 'm';7let port: UserPort = 8080;8 9digit satisfies int;10letter satisfies char;11port satisfies int;String
Destack wants to be "TypeScript++", and thus we also follow JavaScript's string behavior: string length and positional access are defined in terms of UTF-16 code units, and - just like TS's own string iterator - iteration yields Unicode code points (mapping to char).
1const text = "héllo";2 3text.length satisfies isize; // UTF-16 code units, as in JS4 5for (const c of text) {6 c satisfies char; // iteration by code point, as in JS7}Destack is stricter than TS for string indexing: text[i] gives a char, and indexing into a lone surrogate traps.
On native targets, string is the library's String with owned UTF-16 code units; on JS/TS targets, strings use the host engine's representation.