An educational pure functional programming library in TypeScript
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add data/units module with dimensional types

+141
+1
src/data/index.ts
··· 6 6 7 7 export * from "./guards" 8 8 export * from "./array" 9 + export * from "./units"
+140
src/data/units.ts
··· 1 + /** 2 + * Dimensional types for compile-time unit safety. 3 + * 4 + * Prevents mixing incompatible units at compile time. 5 + * 6 + * @example 7 + * ```typescript 8 + * const d = meters(100) 9 + * const t = seconds(10) 10 + * const v = velocity(d, t) // Quantity<number, MetersPerSecond> 11 + * 12 + * // Type error: can't add meters to seconds 13 + * // addQ(d, t) 14 + * 15 + * // OK: same units 16 + * const total = addQ(d, meters(50)) 17 + * ``` 18 + * 19 + * @module data/units 20 + */ 21 + 22 + // ----------------------------------------------------------------------------- 23 + // Unit Phantom Type 24 + // ----------------------------------------------------------------------------- 25 + 26 + declare const __unit: unique symbol 27 + type Unit<U> = { [__unit]: U } 28 + 29 + /** 30 + * Quantity with dimensional unit at type level. 31 + * Prevents mixing incompatible units (meters + seconds = type error). 32 + */ 33 + export type Quantity<T extends number, U> = T & Unit<U> 34 + 35 + // ----------------------------------------------------------------------------- 36 + // Unit Types 37 + // ----------------------------------------------------------------------------- 38 + 39 + export type Meters = "Meters" 40 + export type Seconds = "Seconds" 41 + export type Kilograms = "Kilograms" 42 + export type MetersPerSecond = "MetersPerSecond" 43 + 44 + // ----------------------------------------------------------------------------- 45 + // Constructors 46 + // ----------------------------------------------------------------------------- 47 + 48 + /** 49 + * Create a quantity in meters. 50 + * 51 + * @example 52 + * ```typescript 53 + * const distance = meters(100) 54 + * ``` 55 + */ 56 + export const meters = (n: number): Quantity<number, Meters> => 57 + n as Quantity<number, Meters> 58 + 59 + /** 60 + * Create a quantity in seconds. 61 + * 62 + * @example 63 + * ```typescript 64 + * const time = seconds(60) 65 + * ``` 66 + */ 67 + export const seconds = (n: number): Quantity<number, Seconds> => 68 + n as Quantity<number, Seconds> 69 + 70 + /** 71 + * Create a quantity in kilograms. 72 + * 73 + * @example 74 + * ```typescript 75 + * const mass = kilograms(75) 76 + * ``` 77 + */ 78 + export const kilograms = (n: number): Quantity<number, Kilograms> => 79 + n as Quantity<number, Kilograms> 80 + 81 + // ----------------------------------------------------------------------------- 82 + // Derived Quantities 83 + // ----------------------------------------------------------------------------- 84 + 85 + /** 86 + * Calculate velocity from distance and time. 87 + * 88 + * @example 89 + * ```typescript 90 + * const v = velocity(meters(100), seconds(10)) // 10 m/s 91 + * ``` 92 + */ 93 + export const velocity = ( 94 + distance: Quantity<number, Meters>, 95 + time: Quantity<number, Seconds> 96 + ): Quantity<number, MetersPerSecond> => 97 + ((distance as number) / (time as number)) as Quantity<number, MetersPerSecond> 98 + 99 + // ----------------------------------------------------------------------------- 100 + // Same-Unit Arithmetic 101 + // ----------------------------------------------------------------------------- 102 + 103 + /** 104 + * Add two quantities of the same unit. 105 + * 106 + * @example 107 + * ```typescript 108 + * const total = addQ(meters(10), meters(20)) // 30 meters 109 + * ``` 110 + */ 111 + export const addQ = <U>( 112 + a: Quantity<number, U>, 113 + b: Quantity<number, U> 114 + ): Quantity<number, U> => ((a as number) + (b as number)) as Quantity<number, U> 115 + 116 + /** 117 + * Subtract two quantities of the same unit. 118 + * 119 + * @example 120 + * ```typescript 121 + * const diff = subQ(meters(30), meters(10)) // 20 meters 122 + * ``` 123 + */ 124 + export const subQ = <U>( 125 + a: Quantity<number, U>, 126 + b: Quantity<number, U> 127 + ): Quantity<number, U> => ((a as number) - (b as number)) as Quantity<number, U> 128 + 129 + /** 130 + * Scale a quantity by a scalar value. 131 + * 132 + * @example 133 + * ```typescript 134 + * const doubled = scaleQ(2)(meters(50)) // 100 meters 135 + * ``` 136 + */ 137 + export const scaleQ = 138 + (scalar: number) => 139 + <U>(q: Quantity<number, U>): Quantity<number, U> => 140 + (scalar * (q as number)) as Quantity<number, U>