-
Notifications
You must be signed in to change notification settings - Fork 0
/
unit.ts
58 lines (44 loc) · 2.16 KB
/
unit.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// import { assert } from "console"
import { UnitNameConfig } from "./nameConstruct"
import { UnitShape, UnitBasisType, UnitShapeMap } from "./unitShape"
export interface MathematicalConfig {
hasAbsoluteZero: boolean
isLinear: boolean
}
export abstract class Unit<ThisUnitShapeMap extends UnitShapeMap> {
name: string
abbreviation?: string
names: Array<string>
mathConfig: MathematicalConfig
public get hasAbsoluteZero() : boolean { return this.mathConfig.hasAbsoluteZero }
public get isLinear() : boolean { return this.mathConfig.isLinear }
shape: UnitShape<ThisUnitShapeMap>
constructor(shape: UnitShape<ThisUnitShapeMap>, mathConfig: MathematicalConfig, nameConfig: UnitNameConfig){
this.shape = shape // instanceof UnitShape ? shape : new UnitShape(shape)
this.name = nameConfig.name
this.abbreviation = nameConfig.abbreviation
this.mathConfig = mathConfig
let nameSet = new Set([nameConfig.name])
if (nameConfig.abbreviation) nameSet.add(nameConfig.abbreviation)
if (nameConfig.otherNames) nameConfig.otherNames.forEach((otherName) => {nameSet.add(otherName)})
this.names = new Array<string>(...nameSet.values())
}
// protected test(valuesToTest: Array<number>, maxPercentError: number = 0.01){
// valuesToTest.forEach(x => {assert(this.roundTripError(x) < maxPercentError*x)})
// }
// roundTripError(valueToTest: number){
// let y = this.toBaseSI(this.fromBaseSI(valueToTest))
// return Math.abs(y - valueToTest)
// }
abstract toBaseSI(quantityInThisUnit: number): number
abstract fromBaseSI(quantityInBaseSI: number): number
convertTo(amountInThisUnit:number, toUnit:Unit<ThisUnitShapeMap>): number {
if (this.shape.equal(toUnit.shape)) { // When `ThisUnitShapeMap` is specifically defined, this will always be true.
return toUnit.fromBaseSI(this.toBaseSI(amountInThisUnit))
} else {
throw TypeError(`Unit types do not match: ${this.shape} != ${toUnit.shape}`)
}
}
toString(){ return this.abbreviation ? this.abbreviation : this.name }
}
export default Unit