uom-ts
Version:
Units of measure type safety, with no runtime overhead, supporting multiplication and division!
65 lines (64 loc) • 7.5 kB
TypeScript
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 {};