import { Exponent } from "../exponent";
import { GenericMeasure, NumericOperations } from "./genericMeasure";
import { GenericMeasureStatic } from "./genericMeasureStatic";
import { IsSingleStringLiteral } from "./typeUtils";
import { Unit } from "./unitTypeArithmetic";
type DimensionResult<N, D extends string> = true extends IsSingleStringLiteral<D> ? GenericMeasure<N, {
    [Dim in D]: "1";
}> : never;
/** The functions needed to construct a measure of a given numeric type */
interface GenericMeasureFactory<N> {
    /** The constructor for this generic measure type, useful for doing `instanceof` checks. */
    isMeasure(value: any): value is GenericMeasure<N, any>;
    /**
     * Creates a new dimension base unit.
     * @param dim a unique string literal which names this dimension (e.g. "length")
     * @param symbol the symbol of the base unit of the dimension (e.g. "m")
     * @returns A measure representing 1 base unit of the dimension (1 m)
     */
    dimension<D extends string>(dim: D, symbol?: string): DimensionResult<N, D>;
    /**
     * Creates a dimensionless measure.
     * @param value the value of the measure
     * @returns a measure with no dimensions
     */
    dimensionless(value: N): GenericMeasure<N, Record<never, Exponent | undefined>>;
    /**
     * Creates a measure as a multiple of another measure.
     * @param value the number of measures
     * @param quantity the measure to be multiplied
     * @param symbol an optional unit symbol for this measure
     * @returns a measure of value number of quantities.
     */
    of<U extends Unit>(value: N, quantity: GenericMeasure<N, U>, symbol?: string): GenericMeasure<N, U>;
}
type GenericMeasureCommon<N> = GenericMeasureFactory<N> & GenericMeasureStatic<N>;
type Omit<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
/**
 * A complete measure type for a given numeric type. This consists of:
 * - Static methods to construct measures (e.g. `Measure.of`)
 * - Predefined arithmetic static methods (e.g. `Measure.add`)
 * - User defined static methods (e.g. `Measure.abs`)
 */
export type GenericMeasureType<N, StaticMethods extends object> = GenericMeasureCommon<N> & Omit<StaticMethods, keyof GenericMeasureCommon<N>>;
/**
 * Creates a new measure factory for a given numeric type. The numeric type of the measure is inferred from the
 * parameter.
 * @param num the set of numeric operations needed to implement a measure for an arbitrary numeric type
 * @param staticMethods an object containing methods that should be spread into the static definition of a measure,
 * useful for attaching static math operations to the type.
 * @returns a factory for constructing measures of the given numeric type
 * @example
 * type MyMeasure<U extends Unit> = GenericMeasure<MyNumberType, U>;
 * const MyMeasure = createMeasureType({ ... });
 */
export declare function createMeasureType<N, S extends object = object>(num: NumericOperations<N>, staticMethods?: S): GenericMeasureType<N, S>;
export {};
