Overview
Univerto is built with TypeScript and provides full type safety for all conversions. Each converter module exports its own unit types, and the core library provides shared type definitions.
Unit Types
Each converter module defines its own unit type and constant object.
Pattern
All unit types follow this pattern:
// Type extracted from constant object
export type LengthUnit = (typeof LENGTH_UNIT)[keyof typeof LENGTH_UNIT];
// Frozen constant object with unit values
export const LENGTH_UNIT = Object.freeze({
METER: 'meter',
KILOMETER: 'kilometer',
// ...
});
Example: Length Units
import { LENGTH_UNIT, LengthUnit } from 'univerto/length';
// Type: LengthUnit = 'meter' | 'kilometer' | 'centimeter' | ...
const unit: LengthUnit = LENGTH_UNIT.METER;
// Available length units
const LENGTH_UNIT = {
NANOMETER: 'nanometer',
MICROMETER: 'micrometer',
MILLIMETER: 'millimeter',
CENTIMETER: 'centimeter',
METER: 'meter',
KILOMETER: 'kilometer',
INCH: 'inch',
HAND: 'hand',
FOOT: 'foot',
YARD: 'yard',
CHAIN: 'chain',
FURLONG: 'furlong',
MILE: 'mile',
LEAGUE: 'league'
};
Other Unit Types
Each converter follows the same pattern:
import { MASS_UNIT, MassUnit } from 'univerto/mass';
import { TIME_UNIT, TimeUnit } from 'univerto/time';
import { VOLUME_UNIT, VolumeUnit } from 'univerto/volume';
import { AREA_UNIT, AreaUnit } from 'univerto/area';
import { SPEED_UNIT, SpeedUnit } from 'univerto/speed';
import { DATA_UNIT, DataUnit } from 'univerto/data';
import { CURRENT_UNIT, CurrentUnit } from 'univerto/current';
import { VOLTAGE_UNIT, VoltageUnit } from 'univerto/voltage';
import { FREQUENCY_UNIT, FrequencyUnit } from 'univerto/frequency';
Fraction Interface
Returned by the convertToFraction() method.
interface Fraction {
numerator: number;
denominator: number;
}
Properties
The numerator of the fraction
The denominator of the fraction
Usage
import { LengthUnitConverter } from 'univerto/length';
import { LENGTH_UNIT } from 'univerto/length';
const fraction = LengthUnitConverter
.from(1, LENGTH_UNIT.INCH)
.to(LENGTH_UNIT.CENTIMETER)
.convertToFraction();
// fraction: { numerator: number, denominator: number }
const decimal = fraction.numerator / fraction.denominator;
Rational Class
The Rational class is used internally for high-precision conversions.
class Rational {
constructor(numerator: number, denominator: number);
static fromNumber(number: number): Rational;
static pow(base: number, exp: number): Rational;
toNumber(): number;
toFraction(): { numerator: number; denominator: number };
multiply(other: Rational): Rational;
divide(other: Rational): Rational;
}
Constructor
const rational = new Rational(3, 4); // Represents 3/4
The numerator of the rational number
The denominator of the rational number
Static Methods
fromNumber()
Creates a Rational from a decimal number.
const rational = Rational.fromNumber(5);
// Equivalent to new Rational(5, 1)
The number to convert to a Rational
pow()
Calculates a power as a Rational.
const squared = Rational.pow(10, 2);
// Returns Rational(100, 1)
const inverse = Rational.pow(10, -2);
// Returns Rational(1, 100)
The exponent (can be negative)
Instance Methods
toNumber()
Converts the Rational to a decimal number.
const rational = new Rational(3, 4);
const decimal = rational.toNumber(); // 0.75
toFraction()
Converts the Rational to a Fraction object.
const rational = new Rational(3, 4);
const fraction = rational.toFraction();
// { numerator: 3, denominator: 4 }
multiply()
Multiplies two Rational numbers.
const a = new Rational(2, 3);
const b = new Rational(3, 4);
const result = a.multiply(b);
// Rational(6, 12) = 0.5
The Rational to multiply by
divide()
Divides two Rational numbers.
const a = new Rational(2, 3);
const b = new Rational(3, 4);
const result = a.divide(b);
// Rational(8, 9) ≈ 0.888...
The Rational to divide by
Unit Scale Type
Defines the internal scale representation for each unit.
type UnitScale = {
base: number;
exponent: number;
}
Properties
The base value for the unit scale (e.g., 10 for metric units)
The exponent applied to the base (e.g., -3 for millimeters)
Usage
This type is used internally to define conversion scales:
// Example: Meter scale definition
const meterScale: UnitScale = {
base: 10,
exponent: 0
};
// Example: Kilometer scale definition
const kilometerScale: UnitScale = {
base: 10,
exponent: 3
};
Note: This type is primarily for internal use and custom converter creation.
Generic Type Parameters
The converter factory uses TypeScript generics to ensure type safety.
function createPreciseConverter<
S extends Record<string, Rational>,
Unit extends keyof S
>(scale: S)
Type Parameters
A record mapping unit names to their Rational scale values
The union type of all valid unit keys from the scale
How It Works
The createPreciseConverter function and Rational class are internal utilities used by Univerto to create all the unit converters. They ensure type safety across the conversion methods.
The generic types guarantee that:
fromUnit and targetUnit must be valid keys from the scale object
- Type inference propagates through the method chain
- Invalid units are caught at compile time
This is why you get full TypeScript autocomplete and type checking when using any converter:
import { TimeUnitConverter, TIME_UNIT } from 'univerto/time';
// TypeScript knows exactly which units are valid
TimeUnitConverter.from(10, TIME_UNIT.HOUR); // ✓ Valid
TimeUnitConverter.from(10, 'invalid'); // ✗ Type error
Type Exports
Each converter module exports its types:
// Length module
export { LENGTH_UNIT, LengthUnit } from 'univerto/length';
// Mass module
export { MASS_UNIT, MassUnit } from 'univerto/mass';
// Time module
export { TIME_UNIT, TimeUnit } from 'univerto/time';
// And so on...
Importing Types
import type { LengthUnit } from 'univerto/length';
import type { MassUnit } from 'univerto/mass';
// Use in function signatures
function convertLength(value: number, from: LengthUnit, to: LengthUnit) {
return LengthUnitConverter.from(value, from).to(to).convert();
}
Example Type Usage
Type-Safe Converter Function
import { LengthUnitConverter, LENGTH_UNIT, LengthUnit } from 'univerto/length';
function convert(
value: number,
fromUnit: LengthUnit,
toUnit: LengthUnit
): number {
return LengthUnitConverter
.from(value, fromUnit)
.to(toUnit)
.convert();
}
// TypeScript ensures type safety
const meters = convert(100, LENGTH_UNIT.CENTIMETER, LENGTH_UNIT.METER); // ✓
const invalid = convert(100, 'invalid', LENGTH_UNIT.METER); // ✗ Type error
Generic Conversion Function
type Converter<Unit> = {
from(value: number, unit: Unit): {
to(unit: Unit): {
convert(): number;
convertToFraction(): { numerator: number; denominator: number };
};
};
};
function genericConvert<Unit>(
converter: Converter<Unit>,
value: number,
from: Unit,
to: Unit
): number {
return converter.from(value, from).to(to).convert();
}
// Works with any converter
genericConvert(LengthUnitConverter, 100, LENGTH_UNIT.CM, LENGTH_UNIT.M);
genericConvert(MassUnitConverter, 1000, MASS_UNIT.GRAM, MASS_UNIT.KG);
See Also