Extensible unit of measure conversion with type safety for typescript
This package has functions to handle unit of measures. It works particulary well with typescript in which case it can provice some type safety for amounts of different quantity.
npm install --save uom
The library is compiled to ES5 and no polyfills are required.
NOTE: The base package
uom
does only contain the base SI units. In order to get more units to convert between you also need to install theuom-units
package:
npm install --save uom-units
This feature allows you to convert amounts into different units.
import { Amount } from "uom";
import { Units } from "uom-units";
const amount = Amount.create(10, Units.Meter);
const inch = Amount.valueAs(Units.Inch, amount);
A measure system has a number of BaseUnit
s which is used to create all other derived units in the system which are represented as ProductUnit
or TransformedUnit
. For example in the SI measure system, m
and s
are BaseUnits
s and they can be used to create the m/s
ProductUnit
.
In the case that a derived unit can be known by a different name, an AlternateUnit
can be used. For example in the SI system the derived unit N/m2
is also known as Pascal
.
By using the base units you can create any unit.
import { Amount, Unit } from "uom";
import { Units } from "uom-units";
const myInchUnit = Unit.divideNumber(12.0, Units.Foot);
const amount = Amount.create(10, myInchUnit);
const meter = Amount.valueAs(Units.Meter, amount);
By declaring your functions with a signature of typed Amount you can make sure the right type of amounts are inputs to the function.
import { Amount } from "uom";
import { Units } from "uom-units";
const length1 = Amount.create(10, Units.Meter);
const length2 = Amount.create(10, Units.Inch);
const volume1 = Amount.create(10, Units.CubicMeter);
const result = calculate(length1, length2); // OK
const result = calculate(volume1, length2); // Compile error
function calculate(Amount<Length> length1, Amount<Length> length2): Amount<Length> {
return Amount.plus(length1, length2);
}
Asosciating formatting directly with an Unit
or Quantity
is generally not a good idea. Formatting is application specific and should be implemented within application code. For example, an application may have air flows and water flows that both are of VolumeFlow
quantity. In this case you may want separate labels and default units for air flow and water flow. Associating formatting directly with VolumeFlow
or its units will not solve this. Instead, try tagging each VolumeFlow
field within the application with either air_flow
, or water_flow
and provide different labels and default units per tag.
However if you are just building something smaller and want quick formatting, this package has some utilities for assigning formats directly associated with each Unit
. Specifically you can assign a format consisting of a label and number of decimals for each unit. The actual formats are not present in this package but is provided in external unit packages such as uom-units.
import { Amount, Format } from "uom";
import { Units, UnitsFormat } from "uom-units";
const format = UnitFormat.getUnitFormat(Units.Meter, UnitsFormat);
console.log(
"The amount is " +
Math.round(Amount.valueAs(Units.Meter, amount), format.decimalCount) +
" " +
format.label
);
There is also the buildDerivedSymbol()
function which will derive a symbol for a unit by looking at which base units the unit was created:
import { Amount, Format } from "uom";
import { Units } from "uom-units";
const length = Amount.create(10, Units.MeterPerSecond);
const label = Unit.buildDerivedSymbol(length);
console.log(label); // m/s
This feature can be used to serialize the units for persisting to/from for example a database.
import { Amount, Serialize } from "uom";
import { Units } from "uom-units";
const length = Amount.create(10, Units.Meter);
const serialized = Serialize.amountToString(length);
const deserialized = Serialize.stringToAmount(serialized);
The API is divided into modules, where each module contains functions that operate on a type that is exported from that module. For example the Amount
module exports the type Amount.Amount
and has functions like Amount.plus()
.
For more information, see the full API docs.
Create a PR for addition or changes. Please update the changelog's "unreleased" section with your changes in your PR.
Don't forget to update the changelog before publishing. Then run:
yarn version --patch
yarn version --minor
yarn version --major
This library was inspired by JSR-275. See also this repo, this article. Altough JSR-275 was not accepted it evolved into JSR-363 which is now accepted.