UNPKG

uom-ts

Version:

Units of measure type safety, with no runtime overhead, supporting multiplication and division!

65 lines (64 loc) 7.5 kB
declare type Exponent = -6 | -5 | -4 | -3 | -2 | -1 | 1 | 2 | 3 | 4 | 5 | 6 | undefined; declare type NegativeExponent<T extends Exponent> = (T extends -6 ? 6 : T extends -5 ? 5 : T extends -4 ? 4 : T extends -3 ? 3 : T extends -2 ? 2 : T extends -1 ? 1 : T extends 1 ? -1 : T extends 2 ? -2 : T extends 3 ? -3 : T extends 4 ? -4 : T extends 5 ? -5 : T extends 6 ? -6 : undefined); declare type SumExponents<A extends Exponent, B extends Exponent> = (A extends -6 ? (B extends undefined ? -6 : B extends 1 ? -5 : B extends 2 ? -4 : B extends 3 ? -3 : B extends 4 ? -2 : B extends 5 ? -1 : B extends 6 ? undefined : never) : A extends -5 ? (B extends -1 ? -6 : B extends undefined ? -5 : B extends 1 ? -4 : B extends 2 ? -3 : B extends 3 ? -2 : B extends 4 ? -1 : B extends 5 ? undefined : B extends 6 ? 1 : never) : A extends -4 ? (B extends -2 ? -6 : B extends -1 ? -5 : B extends undefined ? -4 : B extends 1 ? -3 : B extends 2 ? -2 : B extends 3 ? -1 : B extends 4 ? undefined : B extends 5 ? 1 : B extends 6 ? 2 : never) : A extends -3 ? (B extends -3 ? -6 : B extends -2 ? -5 : B extends -1 ? -4 : B extends undefined ? -3 : B extends 1 ? -2 : B extends 2 ? -1 : B extends 3 ? undefined : B extends 4 ? 1 : B extends 5 ? 2 : B extends 6 ? 3 : never) : A extends -2 ? (B extends -4 ? -6 : B extends -3 ? -5 : B extends -2 ? -4 : B extends -1 ? -3 : B extends undefined ? -2 : B extends 1 ? -1 : B extends 2 ? undefined : B extends 3 ? 1 : B extends 4 ? 2 : B extends 5 ? 3 : B extends 6 ? 4 : never) : A extends -1 ? (B extends -5 ? -6 : B extends -4 ? -5 : B extends -3 ? -4 : B extends -2 ? -3 : B extends -1 ? -2 : B extends undefined ? -1 : B extends 1 ? undefined : B extends 2 ? 1 : B extends 3 ? 2 : B extends 4 ? 3 : B extends 5 ? 4 : B extends 6 ? 5 : never) : A extends undefined ? (B extends -6 ? -6 : B extends -5 ? -5 : B extends -4 ? -4 : B extends -3 ? -3 : B extends -2 ? -2 : B extends -1 ? -1 : B extends undefined ? undefined : B extends 1 ? 1 : B extends 2 ? 2 : B extends 3 ? 3 : B extends 4 ? 4 : B extends 5 ? 5 : B extends 6 ? 6 : never) : A extends 1 ? (B extends -6 ? -5 : B extends -5 ? -4 : B extends -4 ? -3 : B extends -3 ? -2 : B extends -2 ? -1 : B extends -1 ? undefined : B extends undefined ? 1 : B extends 1 ? 2 : B extends 2 ? 3 : B extends 3 ? 4 : B extends 4 ? 5 : B extends 5 ? 6 : never) : A extends 2 ? (B extends -6 ? -4 : B extends -5 ? -3 : B extends -4 ? -2 : B extends -3 ? -1 : B extends -2 ? undefined : B extends -1 ? 1 : B extends undefined ? 2 : B extends 1 ? 3 : B extends 2 ? 4 : B extends 3 ? 5 : B extends 4 ? 6 : undefined) : A extends 3 ? (B extends -6 ? -3 : B extends -5 ? -2 : B extends -4 ? -1 : B extends -3 ? undefined : B extends -2 ? 1 : B extends -1 ? 2 : B extends undefined ? 3 : B extends 1 ? 4 : B extends 2 ? 5 : B extends 3 ? 6 : never) : A extends 4 ? (B extends -6 ? -2 : B extends -5 ? -1 : B extends -4 ? undefined : B extends -3 ? 1 : B extends -2 ? 2 : B extends -1 ? 3 : B extends undefined ? 4 : B extends 1 ? 5 : B extends 2 ? 6 : never) : A extends 5 ? (B extends -6 ? -1 : B extends -5 ? undefined : B extends -4 ? 1 : B extends -3 ? 2 : B extends -2 ? 3 : B extends -1 ? 4 : B extends undefined ? 5 : B extends 1 ? 6 : never) : A extends 6 ? (B extends -6 ? undefined : B extends -5 ? 1 : B extends -4 ? 2 : B extends -3 ? 3 : B extends -2 ? 4 : B extends -1 ? 5 : B extends undefined ? 6 : never) : never); declare type DivideExponentsBy2<A extends Exponent> = (A extends -6 ? -3 : A extends -4 ? -2 : A extends -2 ? -1 : A extends 2 ? 1 : A extends 4 ? 2 : A extends 6 ? 3 : A extends undefined ? undefined : never); declare type SubtractExponents<A extends Exponent, B extends Exponent> = SumExponents<A, NegativeExponent<B>>; declare type Exact<A extends object> = A & { __exactKeys: keyof A; }; declare type ObjectWithExponents = { [key: string]: Exponent; }; export declare type AnyUnit = number; export declare type Unit<T extends ObjectWithExponents> = number & Exact<T>; declare type KeysThatHaveNoGivenValue<T, V> = { [K in keyof T]: T[K] extends V ? never : K; }[keyof T]; declare type RemovePropertiesWithGivenValue<T, V> = { [P in KeysThatHaveNoGivenValue<T, V>]: T[P]; }; declare type AssertExponent<T> = T extends Exponent ? T : never; declare type SumExponentsOfTwoObjects<A, B> = { [P in (keyof A | keyof B)]: P extends keyof A ? (P extends keyof B ? SumExponents<AssertExponent<A[P]>, AssertExponent<B[P]>> : AssertExponent<A[P]>) : (P extends keyof B ? AssertExponent<B[P]> : undefined); }; export declare type MultiplyUnits<A, B> = number & Exact<RemovePropertiesWithGivenValue<SumExponentsOfTwoObjects<A, B>, undefined>>; declare type SubtractExponentsOfTwoObjects<A, B> = { [P in (keyof A | keyof B)]: P extends keyof A ? (P extends keyof B ? SubtractExponents<AssertExponent<A[P]>, AssertExponent<B[P]>> : AssertExponent<A[P]>) : (P extends keyof B ? NegativeExponent<AssertExponent<B[P]>> : undefined); }; export declare type DivideUnits<A, B> = number & Exact<RemovePropertiesWithGivenValue<SubtractExponentsOfTwoObjects<A, B>, undefined>>; export declare type SqrtUnit<A extends AnyUnit> = number & Exact<{ [P in keyof A]: DivideExponentsBy2<AssertExponent<A[P]>>; }>; export declare function add<T extends AnyUnit>(a: T, b: T): T; export declare function add<T extends AnyUnit>(a: T): (b: T) => T; export declare function sub<T extends AnyUnit>(a: T, b: T): T; export declare function sub<T extends AnyUnit>(a: T): (b: T) => T; export declare function mul<A extends AnyUnit, B extends AnyUnit>(a: A, b: B): MultiplyUnits<A, B>; export declare function mul<A extends AnyUnit>(a: A): <B extends AnyUnit>(b: B) => MultiplyUnits<A, B>; export declare function div<A extends AnyUnit, B extends AnyUnit>(a: A, b: B): DivideUnits<A, B>; export declare function div<A extends AnyUnit>(a: A): <B extends AnyUnit>(b: B) => DivideUnits<A, B>; export declare function mod<A extends AnyUnit>(a: A, b: A): A; export declare function mod<A extends AnyUnit>(a: A): (b: A) => A; export declare const pow2: <A extends number>(a: A) => MultiplyUnits<A, A>; export declare const sqrt2: <A extends number>(a: A) => SqrtUnit<A>; export declare const negate: <A extends number>(a: A) => A; export declare const abs: <A extends number>(a: A) => A; export declare const floor: <A extends number>(a: A) => A; export declare const ceil: <A extends number>(a: A) => A; export declare const round: <A extends number>(a: A) => A; export declare function eq<A extends AnyUnit>(a: A, b: A): boolean; export declare function eq<A extends AnyUnit>(a: A): (b: A) => boolean; export declare function gt<A extends AnyUnit>(a: A, b: A): boolean; export declare function gt<A extends AnyUnit>(a: A): (b: A) => boolean; export declare function gte<A extends AnyUnit>(a: A, b: A): boolean; export declare function gte<A extends AnyUnit>(a: A): (b: A) => boolean; export declare function lt<A extends AnyUnit>(a: A, b: A): boolean; export declare function lt<A extends AnyUnit>(a: A): (b: A) => boolean; export declare function lte<A extends AnyUnit>(a: A, b: A): boolean; export declare function lte<A extends AnyUnit>(a: A): (b: A) => boolean; export declare type NonEmptyArray<T> = [T, ...T[]]; export declare const isArrayNonEmpty: <T>(a: T[]) => a is NonEmptyArray<T>; export declare const max: <T extends number>(a: NonEmptyArray<T>) => T; export declare const min: <T extends number>(a: NonEmptyArray<T>) => T; export declare const sum: <T extends number>(a: NonEmptyArray<T>) => T; export {};