import { GenericMeasure , NumericOperations } from "./genericMeasure" ; import { createMeasureClass } from "./genericMeasureClass" ; import { GenericMeasureStatic , getGenericMeasureStaticMethods } from "./genericMeasureStatic" ; import { IsSingleStringLiteral } from "./typeUtils" ; import { Unit } from "./unitTypeArithmetic" ; import { dimension } from "./unitValueArithmetic" ; 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 ) : value is GenericMeasure < N , any > ; param dim param symbol returns dimension < D extends string > ( dim , symbol ? ) : DimensionResult < N , D > ; param value returns dimensionless ( value ) : GenericMeasure < N , { } > ; param value param quantity param symbol returns of < U extends Unit > ( value , quantity , symbol ? ) : 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 { } > = GenericMeasureCommon < N > & Omit < StaticMethods , keyof GenericMeasureCommon < N > > ; param num param staticMethods returns example export function createMeasureType < N , S extends { } = { } > ( num , staticMethods ? ) { const Measure = createMeasureClass ( num ) ; const common = { ... getGenericMeasureStaticMethods ( ) , isMeasure : ( value ) : value is GenericMeasure < N , any > => value instanceof Measure , dimensionless : value => new Measure ( value , { } ) , dimension : < D extends string > ( dim , symbol ? ) => new Measure ( num . one ( ) , dimension ( dim , symbol ) , symbol ) as DimensionResult < N , D > , of : < U extends Unit > ( value , quantity , symbol ? ) => new Measure ( num . mult ( value , quantity . value ) , quantity . unit , symbol ) , } ; return { ... ( ( staticMethods || { } ) as any ) , ... common , } ; }