Univerto is written in TypeScript and provides first-class type definitions out of the box. No separate @types package is needed — full type safety is included with every import.
Each converter enforces type-safe unit constants through TypeScript enums. You cannot pass invalid units:
import { TimeUnitConverter, TIME_UNIT } from 'univerto/time'// ✅ Valid — uses defined TIME_UNIT constantsconst milliseconds = TimeUnitConverter .from(1, TIME_UNIT.HOUR) .to(TIME_UNIT.MILLISECOND) .convert()// ❌ Type error — string literals are not allowedconst invalid = TimeUnitConverter .from(1, 'hour') // Type error: Argument of type 'string' is not assignable .to('millisecond') .convert()
IDEs with TypeScript support (VS Code, WebStorm, etc.) provide full autocomplete for:
Converter methods (from, to, convert, convertToFraction)
Unit constants (e.g., TIME_UNIT.HOUR, LENGTH_UNIT.METER)
Return types (number, Fraction, Rational)
The strong typing ensures you catch errors at compile time rather than runtime, making your code more reliable. TypeScript’s autocomplete will suggest available units and methods as you type.
Each converter module exports a unit enum that defines all available units for that category:
// Time unitsimport { TIME_UNIT } from 'univerto/time'TIME_UNIT.NANOSECONDTIME_UNIT.MICROSECONDTIME_UNIT.MILLISECONDTIME_UNIT.SECONDTIME_UNIT.MINUTETIME_UNIT.HOURTIME_UNIT.DAYTIME_UNIT.WEEKTIME_UNIT.MONTHTIME_UNIT.YEARTIME_UNIT.DECADE
// Length unitsimport { LENGTH_UNIT } from 'univerto/length'LENGTH_UNIT.NANOMETERLENGTH_UNIT.MICROMETERLENGTH_UNIT.MILLIMETERLENGTH_UNIT.CENTIMETERLENGTH_UNIT.METERLENGTH_UNIT.KILOMETER// ... and more
Univerto’s converter implementation uses TypeScript generics to ensure type safety across different unit systems. Here’s how the internal architecture works:
// Simplified version of the createPreciseConverter implementationfunction createPreciseConverter<S extends Record<string, Rational>, Unit extends keyof S>( scale: S) { function from(fromQuantity: number, fromUnit: Unit) { function to(targetUnit: Unit) { function convert(): number { /* ... */ } function convertToFraction(): Fraction { /* ... */ } function convertToRational(): Rational { /* ... */ } return { convert, convertToFraction, convertToRational } } return { to } } return { from }}
The generic types ensure that:
fromUnit and targetUnit must be valid keys from the scale object
Type inference propagates through the method chain
You can import types directly for use in your own code:
// Import typesimport type { TimeUnit } from 'univerto/time'import type { LengthUnit } from 'univerto/length'// Use in function signaturesfunction formatTime(value: number, unit: TimeUnit): string { return `${value} ${unit.toLowerCase()}`}function convertDistance(value: number, from: LengthUnit, to: LengthUnit) { // Implementation}
Using import type ensures the import is erased at runtime, keeping your bundle size minimal.