Skip to content

Commit

Permalink
fix: improve modifer logic
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaStevens committed Aug 11, 2023
1 parent 1350c8e commit 673f0b4
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 16 deletions.
84 changes: 76 additions & 8 deletions src/units/modifiers/exponentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ import { assert, type Equals } from "tsafe";
import {
type AbstractUnit,
type Pow,
type PowUnitSubvalues,
type Unit,
type UnitClass,
type UnitConversionRate,
type UnitMeta,
type UnknownAbstractUnit,
type UnknownUnit,
type Unit,
type UnknownUnitClass,
type UnknownUnitConversionRate,
type UnknownUnitMeta,
} from "#uom-types";

/**
Expand All @@ -17,7 +24,20 @@ import {
* @see {@link Pow}
* @see {@link Cubic}
*/
export type Square<T extends UnknownAbstractUnit | UnknownUnit> = Pow<T, 2>;
export type Square<
T extends
| UnknownUnit
| UnknownAbstractUnit
| UnknownUnitConversionRate
| UnknownUnitClass
| UnknownUnitMeta,
> = T extends number
? Pow<T, 2>
: T extends UnknownUnitClass
? UnitClass<PowUnitSubvalues<T["__uom_types__value"], 2>>
: T extends UnknownUnitMeta
? UnitMeta<PowUnitSubvalues<T["__uom_types__value"], 2>>
: never;

/**
* Put the given {@link Unit} to the power of 3.
Expand All @@ -27,14 +47,62 @@ export type Square<T extends UnknownAbstractUnit | UnknownUnit> = Pow<T, 2>;
* @see {@link Pow}
* @see {@link Square}
*/
export type Cubic<T extends UnknownAbstractUnit | UnknownUnit> = Pow<T, 3>;
export type Cubic<
T extends
| UnknownUnit
| UnknownAbstractUnit
| UnknownUnitConversionRate
| UnknownUnitClass
| UnknownUnitMeta,
> = T extends number
? Pow<T, 3>
: T extends UnknownUnitClass
? UnitClass<PowUnitSubvalues<T["__uom_types__value"], 3>>
: T extends UnknownUnitMeta
? UnitMeta<PowUnitSubvalues<T["__uom_types__value"], 3>>
: never;

// Tests
// eslint-disable-next-line functional/no-conditional-statements
if (import.meta.vitest !== undefined) {
assert<Equals<Square<Unit<{ a: 1 }>>, Unit<{ a: 2 }>>>();
assert<Equals<Square<AbstractUnit<{ a: 1 }>>, AbstractUnit<{ a: 2 }>>>();
const { describe, it } = import.meta.vitest;

describe("Square", () => {
it("squares a unit", () => {
assert<
Equals<Square<Unit<{ a: 1 }, { b: 2 }>>, Unit<{ a: 2 }, { b: 4 }>>
>();
assert<Equals<Square<AbstractUnit<{ a: 1 }>>, AbstractUnit<{ a: 2 }>>>();
assert<
Equals<
Square<UnitConversionRate<{ a: 1 }>>,
UnitConversionRate<{ a: 2 }>
>
>();
assert<
Equals<Square<UnitClass<{ a: 1; b: 2 }>>, UnitClass<{ a: 2; b: 4 }>>
>();
assert<
Equals<Square<UnitMeta<{ a: 1; b: 2 }>>, UnitMeta<{ a: 2; b: 4 }>>
>();
});
});

assert<Equals<Cubic<Unit<{ a: 1 }>>, Unit<{ a: 3 }>>>();
assert<Equals<Cubic<AbstractUnit<{ a: 1 }>>, AbstractUnit<{ a: 3 }>>>();
describe("Cubic", () => {
it("cubes a unit", () => {
assert<
Equals<Cubic<Unit<{ a: 1 }, { b: 2 }>>, Unit<{ a: 3 }, { b: 6 }>>
>();
assert<Equals<Cubic<AbstractUnit<{ a: 1 }>>, AbstractUnit<{ a: 3 }>>>();
assert<
Equals<
Cubic<UnitConversionRate<{ a: 1 }>>,
UnitConversionRate<{ a: 3 }>
>
>();
});
assert<
Equals<Cubic<UnitClass<{ a: 1; b: 2 }>>, UnitClass<{ a: 3; b: 6 }>>
>();
assert<Equals<Cubic<UnitMeta<{ a: 1; b: 2 }>>, UnitMeta<{ a: 3; b: 6 }>>>();
});
}
63 changes: 55 additions & 8 deletions src/units/modifiers/reciprocal.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { assert, type Equals } from "tsafe";

import {
type UnitClass,
type InverseUnitSubvalues,
type UnknownUnitClass,
type AbstractUnit,
type Inverse,
type InverseUnitSubvalues,
type Unit,
type UnitClass,
type UnitConversionRate,
type UnitMeta,
type UnknownAbstractUnit,
type UnknownUnit,
type Unit,
type UnknownUnitClass,
type UnknownUnitConversionRate,
type UnknownUnitMeta,
} from "#uom-types";

/**
Expand All @@ -14,15 +22,54 @@ import {
* @group Modifiers
* @category General
*/
export type Reciprocal<T extends UnknownAbstractUnit | UnknownUnit> =
Inverse<T>;
export type Reciprocal<
T extends
| UnknownUnit
| UnknownAbstractUnit
| UnknownUnitConversionRate
| UnknownUnitClass
| UnknownUnitMeta,
> = T extends number
? Inverse<T>
: T extends UnknownUnitClass
? UnitClass<InverseUnitSubvalues<T["__uom_types__value"]>>
: T extends UnknownUnitMeta
? UnitMeta<InverseUnitSubvalues<T["__uom_types__value"]>>
: never;

/**
* Invert the {@link UnitClass}.
*
* @group Unit Class Modifiers
* @category General
* @deprecated Use {@link Reciprocal} instead.
*/
export type ReciprocalUnitClass<T extends UnknownUnitClass> = UnitClass<
InverseUnitSubvalues<T["__uom_types__value"]>
>;

// Tests
if (import.meta.vitest !== undefined) {
const { describe, it } = import.meta.vitest;

describe("Reciprocal", () => {
it("reciprocals a unit", () => {
assert<
Equals<Reciprocal<Unit<{ a: 1 }, { b: 2 }>>, Unit<{ a: -1 }, { b: -2 }>>
>();
assert<
Equals<Reciprocal<AbstractUnit<{ a: 1 }>>, AbstractUnit<{ a: -1 }>>
>();
assert<
Equals<
Reciprocal<UnitConversionRate<{ a: 1 }>>,
UnitConversionRate<{ a: -1 }>
>
>();
});
assert<
Equals<Reciprocal<UnitClass<{ a: 1; b: 2 }>>, UnitClass<{ a: -1; b: -2 }>>
>();
assert<
Equals<Reciprocal<UnitMeta<{ a: 1; b: 2 }>>, UnitMeta<{ a: -1; b: -2 }>>
>();
});
}

0 comments on commit 673f0b4

Please sign in to comment.