Skip to content

Commit

Permalink
feat: add Unit Functions Pow and Root
Browse files Browse the repository at this point in the history
these are renamed versions of MultiplyUnitExponents and DivideUnitExponents which have now been
deprecated.
  • Loading branch information
RebeccaStevens committed Aug 9, 2023
1 parent 2fd3baa commit ae679dc
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 171 deletions.
22 changes: 22 additions & 0 deletions src/deprecated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type Exponent } from "./exponents";
import { type Pow, type Root } from "./units";

/**
* Multiple the exponent values of a unit by a number.
*
* @deprecated Use {@link Pow} instead.
*/
export type MultiplyUnitExponents<T extends number, E extends Exponent> = Pow<
T,
E
>;

/**
* Divide the exponent values of a unit by a number.
*
* @deprecated Use {@link Root} instead.
*/
export type DivideUnitExponents<T extends number, E extends Exponent> = Root<
T,
E
>;
4 changes: 2 additions & 2 deletions src/functions-ho/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import {
type AbstractUnit,
type Divide,
type DivideUnitExponents,
type Root,
type Inverse,
type Multiply,
type Unit,
Expand Down Expand Up @@ -102,7 +102,7 @@ type PowFunction<E extends number, B extends number> = E extends UnknownUnit
? AbstractUnit<{}>
: 1
: E extends 0.5
? (b: B) => DivideUnitExponents<B, 2>
? (b: B) => Root<B, 2>
: E extends 1
? (b: B) => B
: E extends 2
Expand Down
9 changes: 3 additions & 6 deletions src/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import {
type AbstractUnit,
type Divide,
type DivideUnitExponents,
type Inverse,
type Multiply,
type Root,
type Unit,
type UnknownAbstractUnit,
type UnknownUnit,
Expand Down Expand Up @@ -124,10 +124,7 @@ export function pow<B extends number>(
*
* @category Math
*/
export function pow<B extends number>(
base: B,
exponent: 0.5,
): DivideUnitExponents<B, 2>;
export function pow<B extends number>(base: B, exponent: 0.5): Root<B, 2>;

/**
* Put a number to the power of 1.
Expand Down Expand Up @@ -186,7 +183,7 @@ export function pow(base: number, exponent: number): number {
*
* @category Math
*/
export function sqrt<T extends number>(value: T): DivideUnitExponents<T, 2> {
export function sqrt<T extends number>(value: T): Root<T, 2> {
return pow(value, 0.5);
}

Expand Down
9 changes: 5 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ export type {
SubExponents,
SumExponents,
} from "./exponents";
export type {
DivideUnitExponents,
MultiplyUnitExponents,
} from "./unit-exponents";
export type { DivideUnitExponents, MultiplyUnitExponents } from "./deprecated";
export type {
Divide,
DivideUnitSubvalues,
Inverse,
InverseUnitSubvalues,
Multiply,
MultiplyUnitSubvalues,
Pow,
PowUnitSubvalues,
Root,
RootUnitSubvalues,
} from "./units";
150 changes: 0 additions & 150 deletions src/unit-exponents.ts

This file was deleted.

120 changes: 118 additions & 2 deletions src/units.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { assert, type Equals } from "tsafe";

import {
type UnitSubvalues,
type AbstractUnit,
type Unit,
type UnitSubvalues,
type UnknownAbstractUnit,
type UnknownUnit,
} from "./core";
import { type NegativeExponent, type SumExponents } from "./exponents";
import {
type DivideExponents,
type Exponent,
type MultiplyExponents,
type NegativeExponent,
type SumExponents,
} from "./exponents";
import {
type ExcludeUnitZeroSubvalues,
type FlatternAlias,
Expand Down Expand Up @@ -98,3 +107,110 @@ export type DivideUnitSubvalues<
A extends UnitSubvalues,
B extends UnitSubvalues,
> = MultiplyUnitSubvalues<A, InverseUnitSubvalues<B>>;

/**
* Put a unit to the power of an exponent.
*
* @group Unit Functions
*/
export type Pow<T extends number, N extends Exponent> = T extends Unit<
infer Config,
infer Meta
>
? Unit<
FlatternAlias<PowUnitSubvalues<Config, N>>,
FlatternAlias<PowUnitSubvalues<Meta, N>>
>
: T extends AbstractUnit<infer Config>
? AbstractUnit<FlatternAlias<PowUnitSubvalues<Config, N>>>
: number;

/**
* Put each subvalue of a unit to the power of an exponent.
*
* @group Unit Subvalue Functions
*/
export type PowUnitSubvalues<T extends UnitSubvalues, E extends Exponent> = {
[S in keyof T]: MultiplyExponents<GetExponent<T, S>, E>;
};

/**
* Take the nth root of a unit.
*
* @group Unit Functions
*/
export type Root<T extends number, N extends Exponent> = T extends Unit<
infer Config,
infer Meta
>
? Unit<
FlatternAlias<RootUnitSubvalues<Config, N>>,
FlatternAlias<RootUnitSubvalues<Meta, N>>
>
: T extends AbstractUnit<infer Config>
? AbstractUnit<FlatternAlias<RootUnitSubvalues<Config, N>>>
: number;

/**
* Take the nth root of each subvalue of a unit.
*
* @group Unit Subvalue Functions
*/
export type RootUnitSubvalues<T extends UnitSubvalues, E extends Exponent> = {
[S in keyof T]: DivideExponents<GetExponent<T, S>, E>;
};

// Tests
// eslint-disable-next-line eslint-comments/disable-enable-pair
/* eslint-disable functional/no-conditional-statements, functional/no-expression-statements, functional/no-return-void */
if (import.meta.vitest !== undefined) {
const { describe, it } = import.meta.vitest;

describe("Pow", () => {
it("works with Units", () => {
assert<Equals<Pow<Unit<{ a: 1 }>, 2>, Unit<{ a: 2 }>>>();
assert<Equals<Pow<Unit<{ a: 2 }>, 2>, Unit<{ a: 4 }>>>();
assert<Equals<Pow<Unit<{ a: -2 }>, 2>, Unit<{ a: -4 }>>>();
assert<Equals<Pow<Unit<{ a: 1 }>, 3>, Unit<{ a: 3 }>>>();
assert<Equals<Pow<Unit<{ a: 2 }>, 3>, Unit<{ a: 6 }>>>();
assert<Equals<Pow<Unit<{ a: -2 }>, 3>, Unit<{ a: -6 }>>>();
});

it("works with AbstractUnit", () => {
assert<Equals<Pow<AbstractUnit<{ a: 1 }>, 2>, AbstractUnit<{ a: 2 }>>>();
assert<Equals<Pow<AbstractUnit<{ a: 2 }>, 2>, AbstractUnit<{ a: 4 }>>>();
assert<
Equals<Pow<AbstractUnit<{ a: -2 }>, 2>, AbstractUnit<{ a: -4 }>>
>();
assert<Equals<Pow<AbstractUnit<{ a: 1 }>, 3>, AbstractUnit<{ a: 3 }>>>();
assert<Equals<Pow<AbstractUnit<{ a: 2 }>, 3>, AbstractUnit<{ a: 6 }>>>();
assert<
Equals<Pow<AbstractUnit<{ a: -2 }>, 3>, AbstractUnit<{ a: -6 }>>
>();
});
});

describe("Root", () => {
it("works with Units", () => {
assert<Equals<Root<Unit<{ a: 4 }>, 2>, Unit<{ a: 2 }>>>();
assert<Equals<Root<Unit<{ a: 2 }>, 2>, Unit<{ a: 1 }>>>();
assert<Equals<Root<Unit<{ a: -2 }>, 2>, Unit<{ a: -1 }>>>();
assert<Equals<Root<Unit<{ a: 6 }>, 3>, Unit<{ a: 2 }>>>();
assert<Equals<Root<Unit<{ a: 3 }>, 3>, Unit<{ a: 1 }>>>();
assert<Equals<Root<Unit<{ a: -3 }>, 3>, Unit<{ a: -1 }>>>();
});

it("works with AbstractUnit", () => {
assert<Equals<Root<AbstractUnit<{ a: 4 }>, 2>, AbstractUnit<{ a: 2 }>>>();
assert<Equals<Root<AbstractUnit<{ a: 2 }>, 2>, AbstractUnit<{ a: 1 }>>>();
assert<
Equals<Root<AbstractUnit<{ a: -2 }>, 2>, AbstractUnit<{ a: -1 }>>
>();
assert<Equals<Root<AbstractUnit<{ a: 6 }>, 3>, AbstractUnit<{ a: 2 }>>>();
assert<Equals<Root<AbstractUnit<{ a: 3 }>, 3>, AbstractUnit<{ a: 1 }>>>();
assert<
Equals<Root<AbstractUnit<{ a: -3 }>, 3>, AbstractUnit<{ a: -1 }>>
>();
});
});
}

0 comments on commit ae679dc

Please sign in to comment.