https://github.com/eibens/unit
Extensible, strongly-typed unit conversions in TypeScript for Deno.
https://github.com/eibens/unit
conversion deno typescript unit utility
Last synced: 2 months ago
JSON representation
Extensible, strongly-typed unit conversions in TypeScript for Deno.
- Host: GitHub
- URL: https://github.com/eibens/unit
- Owner: eibens
- License: mit
- Created: 2021-12-27T14:11:49.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-04-23T19:20:55.000Z (about 3 years ago)
- Last Synced: 2025-01-22T13:48:11.085Z (over 1 year ago)
- Topics: conversion, deno, typescript, unit, utility
- Language: TypeScript
- Homepage:
- Size: 15.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# unit
[unit](#) is an extensible library for strongly-typed unit conversions in
TypeScript for Deno.
[](LICENSE)
[](https://github.com/eibens/unit)
[](https://github.com/eibens/unit/actions/workflows/ci.yml)
[](https://codecov.io/gh/eibens/unit)
# Conversions
The [`convert` function](convert.ts) converts a numeric `value` in a `source`
unit to a value in a `target` unit using a `system` of conversions. For example,
the code below converts the value `0.5` from `"hour"` to `"second"` using a
[predefined system](#predefined-systems), and tests whether the result is
`1800`. The names of the units are strongly-typed:
```ts
import { convert, SiTime } from "./mod.ts";
const result = convert({
value: 0.5,
source: "hour",
target: "second",
system: SiTime.getSystem(),
});
console.assert(result === 1800);
```
# Systems
A system is a set of [`Conversion`](conversion.ts) objects. For example, the
code below defines conversions from `"hour"` to `"minute"` and from `"minute"`
to `"second"`. Plugging this system into the `convert` function yields the same
result as before. Note how there is no explicit conversion function from
`"hour"` to `"second"`, but an implicit conversion exists via the `"minute"`
unit. The `convert` function automatically finds the `hour -> minute -> second`
path and chains the conversion functions:
```ts
import { Conversion, convert } from "./mod.ts";
type Unit =
| "hour"
| "second"
| "minute";
function getSystem(): Conversion[] {
return [{
source: "hour",
target: "minute",
apply: (value) => value * 60,
}, {
source: "minute",
target: "second",
apply: (value) => value * 60,
}];
}
const result = convert({
value: 0.5,
source: "hour",
target: "second",
system: getSystem(),
});
console.assert(result === 1800);
```
## Parametric Systems
Systems sometimes depend on external parameters. For example, in a
[musical time unit system](systems/music_time.ts) a `tempo` parameter is needed
to convert from `"beat"` to `"second"`. Parameters can be passed to the
`getSystem` function:
```ts
import { Conversion, convert } from "./mod.ts";
type Unit =
| "beat"
| "second";
type Options = {
tempo: number;
};
function getSystem(options: Options): Conversion[] {
return [{
source: "beat",
target: "second",
apply: (value) => value * 60 / options.tempo,
}];
}
const result = convert({
value: 1,
source: "beat",
target: "second",
system: getSystem({
tempo: 120,
}),
});
console.assert(result === 0.5);
```
## Generic Systems
Generic systems are not bound to a specific set of units and can thus be used as
templates for other unit systems. For example, the
[`Factor` system](systems/factor.ts) takes a `target` unit, numeric `factor`,
and `source` unit, and returns a system that consists of two conversions: one
multiplies the `source` unit by the `factor` and one divides the `target` unit
by the `factor`:
```ts
import { Conversion, convert, Factor } from "./mod.ts";
type Unit =
| "minute"
| "second";
const result = convert({
value: 30,
source: "second",
target: "minute",
system: Factor.getSystem("minute", 60, "second"),
});
console.assert(result === 0.5);
```
## Composite Systems
Since a system is an array of conversions, two systems can be merged by
concatenating their arrays. For example, one can build a system for converting
between `"hour"`, `"minute"`, and `"second"` by concatenating two
[`Factor` systems](systems/factor.ts):
```ts
import { Conversion, convert, Factor } from "./mod.ts";
type Unit =
| "hour"
| "second"
| "minute";
function getSystem(): Conversion[] {
return [
...Factor.getSystem("hour", 60, "minute"),
...Factor.getSystem("minute", 60, "second"),
];
}
const result = convert({
value: 0.5,
source: "hour",
target: "second",
system: getSystem(),
});
console.assert(result === 1800);
```
## Predefined Systems
The package comes with predefined systems, each with a `Unit` type and a
`getSystem` function that generates a minimal spanning-tree of conversions.
While still very limited in number, they may serve as a starting point for
building custom systems:
- [`SiTime`](systems/si_time.ts) is a constant system for SI time units.
- [`MusicTime`](systems/music_time.ts) is a parametric system for musical time
units.
- [`Factor`](systems/factor.ts) is a generic system for multiplicative
conversions.
# Future Work
- Unit abbreviations or aliases (e.g. `second = s`).
- Unit parsing (e.g. `"1s" -> [1, "second"]`).
- Predefined systems for common units (e.g. weight, length).
- Additive conversion (e.g. `1h2m3s -> 1h + 2m + 3s`).
- Multi-dimensional conversions (e.g. `1 m/s -> 3.6 km/h`).
- More generic systems (e.g. `Linear` for `K -> °C`, `Exp` for `dB -> ratio`).
- Conversion DSL (e.g. `time("0.5h").to("s")`)