0
# Data Types and Type System
1
2
This document covers Math.js's rich type system, including all built-in data types, type constructors, conversion functions, type checking utilities, and working with the extensible type system that supports numbers, BigNumbers, complex numbers, fractions, units, matrices, and more.
3
4
## Import
5
6
```typescript
7
import {
8
// Type constructors
9
bignumber, bigint, boolean, complex, fraction, matrix, number, string, unit,
10
// Type checking functions
11
isNumber, isBigNumber, isBigInt, isComplex, isFraction, isUnit,
12
isMatrix, isArray, isString, isBoolean, isNull, isUndefined,
13
// Utility functions
14
typeOf, clone, format, numeric,
15
// Special values
16
Infinity, NaN, null, undefined
17
} from 'mathjs'
18
```
19
20
## Core Numeric Types
21
22
### JavaScript Numbers
23
24
```typescript
25
number(value?: MathType, valuelessUnit?: Unit | string): number
26
```
27
{ .api }
28
29
```typescript
30
// Create numbers
31
number() // 0
32
number(5) // 5
33
number('3.14') // 3.14
34
number(true) // 1
35
number(false) // 0
36
37
// Convert from other types
38
number(bignumber('123.456')) // 123.456
39
number(fraction(3, 4)) // 0.75
40
number(complex(5, 0)) // 5 (real part, imaginary must be 0)
41
42
// With units (extract numeric value)
43
number(unit('5 m'), 'cm') // 500 (convert to cm, return number)
44
number(unit('100 fahrenheit'), 'celsius') // ~37.78
45
46
// Limitations of JavaScript numbers
47
number(9007199254740992) // 9007199254740992 (MAX_SAFE_INTEGER + 1)
48
number(9007199254740993) // 9007199254740992 (precision lost!)
49
50
// Special values
51
number(Infinity) // Infinity
52
number(-Infinity) // -Infinity
53
number(NaN) // NaN
54
```
55
56
### BigNumber (Arbitrary Precision Decimals)
57
58
```typescript
59
bignumber(value?: MathType): BigNumber
60
```
61
{ .api }
62
63
```typescript
64
// Create BigNumbers for high precision
65
bignumber('0.1') // BigNumber(0.1) - exact representation
66
bignumber('123456789012345678901234567890.123456789') // Full precision
67
68
// Avoid precision issues with regular numbers
69
0.1 + 0.2 // 0.30000000000000004 (JavaScript number)
70
bignumber('0.1').plus('0.2') // BigNumber(0.3) - exact
71
72
// Large integers without precision loss
73
bignumber('9007199254740993') // Exact (beyond JS safe integer limit)
74
bignumber('999999999999999999999999999999') // Arbitrary size
75
76
// Convert from other types
77
bignumber(123) // BigNumber(123)
78
bignumber(fraction(1, 3)) // BigNumber(0.333...) with configured precision
79
bignumber(3.14159) // BigNumber(3.14159)
80
81
// Mathematical operations
82
const a = bignumber('123.456')
83
const b = bignumber('789.012')
84
a.plus(b) // BigNumber(912.468)
85
a.minus(b) // BigNumber(-665.556)
86
a.times(b) // BigNumber(97408.265472)
87
a.div(b) // BigNumber(0.1564...)
88
89
// Configuration affects precision
90
import { create, all } from 'mathjs'
91
const math = create(all, { precision: 64 }) // 64 significant digits
92
math.bignumber('1').div('3') // Very high precision result
93
```
94
95
### BigInt (Arbitrary Precision Integers)
96
97
```typescript
98
bigint(value?: MathType): bigint
99
```
100
{ .api }
101
102
```typescript
103
// Create BigInts for large integers
104
bigint(123) // 123n
105
bigint('9007199254740993') // 9007199254740993n
106
bigint('999999999999999999999999999999') // Huge integer
107
108
// Convert from other types
109
bigint(bignumber('123')) // 123n
110
bigint(fraction(10, 2)) // 5n (must be integer fraction)
111
112
// BigInt arithmetic (uses JavaScript BigInt operators)
113
const x = bigint('123456789012345678901234567890')
114
const y = bigint('987654321098765432109876543210')
115
// Use standard BigInt operations: +, -, *, /, %, **
116
117
// Note: BigInt only supports integers
118
bigint(3.14) // Error: cannot convert non-integer
119
bigint(fraction(1, 3)) // Error: fraction is not integer
120
```
121
122
### Complex Numbers
123
124
```typescript
125
complex(re: MathType, im?: MathType): Complex
126
complex(value?: MathType): Complex
127
```
128
{ .api }
129
130
```typescript
131
// Create complex numbers
132
complex(3, 4) // 3 + 4i
133
complex(2) // 2 + 0i (real number)
134
complex() // 0 + 0i
135
136
// From string notation
137
complex('2 + 3i') // 2 + 3i
138
complex('5i') // 0 + 5i
139
complex('-2 - 7i') // -2 - 7i
140
141
// From polar form (using Euler's formula)
142
const r = 5
143
const theta = pi / 4
144
complex(multiply(r, cos(theta)), multiply(r, sin(theta))) // 5∠45° in rectangular
145
146
// Complex arithmetic
147
const z1 = complex(1, 2) // 1 + 2i
148
const z2 = complex(3, -1) // 3 - 1i
149
150
add(z1, z2) // Complex(4, 1) = 4 + 1i
151
subtract(z1, z2) // Complex(-2, 3) = -2 + 3i
152
multiply(z1, z2) // Complex(5, 5) = 5 + 5i
153
divide(z1, z2) // Complex(0.1, 0.7) = 0.1 + 0.7i
154
155
// Complex functions
156
abs(z1) // √5 (magnitude)
157
arg(z1) // atan2(2, 1) (phase angle)
158
conj(z1) // Complex(1, -2) = 1 - 2i (conjugate)
159
re(z1) // 1 (real part)
160
im(z1) // 2 (imaginary part)
161
162
// Complex math functions
163
sqrt(complex(-1, 0)) // Complex(0, 1) = i
164
exp(complex(0, pi)) // Complex(-1, 0) ≈ -1 (Euler's identity)
165
sin(complex(0, 1)) // Complex(0, 1.175...) = i*sinh(1)
166
```
167
168
### Fractions (Exact Rational Numbers)
169
170
```typescript
171
fraction(numerator: MathType, denominator?: MathType): Fraction
172
fraction(value?: MathType): Fraction
173
```
174
{ .api }
175
176
```typescript
177
// Create fractions
178
fraction(1, 3) // Fraction(1/3)
179
fraction(22, 7) // Fraction(22/7) ≈ π approximation
180
fraction(0.5) // Fraction(1/2) - exact conversion
181
fraction('0.125') // Fraction(1/8)
182
183
// Exact arithmetic (no rounding errors)
184
const third = fraction(1, 3)
185
const sixth = fraction(1, 6)
186
add(third, sixth) // Fraction(1/2) - exact result
187
multiply(third, 3) // Fraction(1) - exact result
188
189
// Avoid decimal precision issues
190
fraction(1, 3).toString() // "1/3"
191
number(fraction(1, 3)) // 0.3333333...
192
193
// Fraction operations
194
const a = fraction(2, 3)
195
const b = fraction(3, 4)
196
add(a, b) // Fraction(17/12)
197
multiply(a, b) // Fraction(1/2)
198
divide(a, b) // Fraction(8/9)
199
pow(a, 2) // Fraction(4/9)
200
201
// Convert decimals to fractions
202
fraction(0.75) // Fraction(3/4)
203
fraction(0.333333) // Fraction(1/3) - recognizes pattern
204
fraction(0.142857142857) // Fraction(1/7) - recognizes repeating decimal
205
206
// Mixed numbers and improper fractions
207
const improper = fraction(7, 3) // 7/3 = 2⅓
208
improper.valueOf() // 2.333...
209
```
210
211
## Composite Types
212
213
### Units (Quantities with Dimensions)
214
215
```typescript
216
unit(value?: string | number, unit?: string): Unit
217
```
218
{ .api }
219
220
```typescript
221
// Create units (see units.md for comprehensive coverage)
222
unit('5 meter') // 5 meter
223
unit(10, 'cm') // 10 cm
224
unit('25 celsius') // 25 celsius
225
226
// Units with different numeric types
227
unit(bignumber('3.14159'), 'radian') // High-precision angle
228
unit(complex(1, 1), 'meter') // Complex-valued length
229
unit(fraction(1, 2), 'hour') // Exact time fraction
230
231
// Compound units
232
unit('60 km/h') // Speed
233
unit('9.8 m/s^2') // Acceleration
234
unit('100 J/(mol*K)') // Specific heat capacity
235
236
// Unit conversion preserves numeric type
237
const bigDistance = unit(bignumber('1000.123456789'), 'meter')
238
to(bigDistance, 'km') // BigNumber result: 1.000123456789 km
239
```
240
241
### Matrices and Arrays
242
243
```typescript
244
matrix(data: MathArray | Matrix, format?: 'dense' | 'sparse', dataType?: string): Matrix
245
```
246
{ .api }
247
248
```typescript
249
// Create matrices from arrays
250
matrix([[1, 2], [3, 4]]) // 2×2 dense matrix
251
matrix([1, 2, 3, 4]) // Column vector (4×1)
252
253
// Specify format and data type
254
matrix([[1, 0, 0], [0, 2, 0], [0, 0, 3]], 'sparse') // Sparse matrix
255
matrix([[1, 2], [3, 4]], 'dense', 'number') // Explicit number type
256
257
// Mixed-type matrices
258
matrix([
259
[1, bignumber('2.5')],
260
[fraction(3, 4), complex(1, 2)]
261
]) // Each element can have different numeric type
262
263
// Specialized matrices
264
identity(3) // 3×3 identity matrix
265
zeros([2, 3]) // 2×3 zero matrix
266
ones([3, 2]) // 3×2 matrix of ones
267
range(0, 10, 2) // [0, 2, 4, 6, 8] as matrix
268
269
// Matrix properties
270
const A = matrix([[1, 2, 3], [4, 5, 6]])
271
size(A) // [2, 3] - dimensions
272
A.storage() // 'dense' - storage format
273
A.datatype() // 'number' - element data type
274
```
275
276
### Strings
277
278
```typescript
279
string(value?: MathType): string
280
```
281
{ .api }
282
283
```typescript
284
// Convert values to strings
285
string(123) // '123'
286
string(bignumber('123.456')) // '123.456'
287
string(complex(2, 3)) // '2 + 3i'
288
string(fraction(1, 3)) // '1/3'
289
string(unit('5 meter')) // '5 meter'
290
string([[1, 2], [3, 4]]) // '[[1, 2], [3, 4]]'
291
292
// Format control (see format function for advanced options)
293
format(bignumber('123.456789'), { precision: 3 }) // '123'
294
format(complex(1, 2), { notation: 'exponential' }) // '1e+0 + 2e+0i'
295
```
296
297
### Booleans
298
299
```typescript
300
boolean(value?: MathType): boolean
301
```
302
{ .api }
303
304
```typescript
305
// Convert to boolean
306
boolean(1) // true
307
boolean(0) // false
308
boolean('true') // true
309
boolean('false') // false
310
boolean('') // false
311
boolean('hello') // true (non-empty string)
312
313
// Numeric conversions
314
boolean(bignumber('0')) // false
315
boolean(bignumber('1')) // true
316
boolean(complex(0, 0)) // false
317
boolean(complex(1, 0)) // true
318
319
// Special values
320
boolean(null) // false
321
boolean(undefined) // false
322
boolean(NaN) // false
323
boolean(Infinity) // true
324
```
325
326
## Type Checking Functions
327
328
### Basic Type Checks
329
330
```typescript
331
// Number type checks
332
isNumber(x: any): boolean
333
isBigNumber(x: any): boolean
334
isBigInt(x: any): boolean
335
isNumeric(x: any): boolean
336
```
337
{ .api }
338
339
```typescript
340
// Check specific numeric types
341
isNumber(5) // true
342
isNumber('5') // false
343
isBigNumber(bignumber('5')) // true
344
isBigInt(5n) // true
345
isNumeric(5) // true
346
isNumeric(bignumber('5')) // true
347
isNumeric('5') // false
348
349
// Value checking
350
isInteger(5) // true
351
isInteger(5.5) // false
352
isNaN(NaN) // true
353
isNaN(5) // false
354
isZero(0) // true
355
isZero(bignumber('0')) // true
356
isPositive(5) // true
357
isNegative(-3) // true
358
```
359
360
### Complex Type Checks
361
362
```typescript
363
// Complex and composite types
364
isComplex(x: any): boolean
365
isFraction(x: any): boolean
366
isUnit(x: any): boolean
367
isMatrix(x: any): boolean
368
isArray(x: any): boolean
369
```
370
{ .api }
371
372
```typescript
373
isComplex(complex(1, 2)) // true
374
isComplex(5) // false (real numbers are not complex objects)
375
isFraction(fraction(1, 2)) // true
376
isUnit(unit('5 m')) // true
377
isMatrix(matrix([[1, 2]])) // true
378
isArray([1, 2, 3]) // true
379
isArray(matrix([1, 2, 3])) // false (matrix is not array)
380
381
// Matrix type specifics
382
isDenseMatrix(matrix([[1, 2]])) // true
383
isSparseMatrix(sparse([[1, 0]])) // true
384
```
385
386
### Collection and Structure Checks
387
388
```typescript
389
isCollection(x: any): boolean // Matrix or Array
390
isRange(x: any): boolean
391
isIndex(x: any): boolean
392
isResultSet(x: any): boolean
393
```
394
{ .api }
395
396
```typescript
397
isCollection([1, 2, 3]) // true
398
isCollection(matrix([1, 2, 3])) // true
399
isCollection(5) // false
400
401
isRange(range(0, 10)) // true
402
isIndex(index(0, 1)) // true
403
```
404
405
### General Type Checks
406
407
```typescript
408
isString(x: any): boolean
409
isBoolean(x: any): boolean
410
isFunction(x: any): boolean
411
isDate(x: any): boolean
412
isRegExp(x: any): boolean
413
isObject(x: any): boolean
414
isNull(x: any): boolean
415
isUndefined(x: any): boolean
416
```
417
{ .api }
418
419
```typescript
420
isString('hello') // true
421
isBoolean(true) // true
422
isFunction(sin) // true
423
isDate(new Date()) // true
424
isRegExp(/pattern/) // true
425
isObject({a: 1}) // true
426
isNull(null) // true
427
isUndefined(undefined) // true
428
```
429
430
### AST Node Type Checks
431
432
```typescript
433
// Check AST node types (for expression parsing)
434
isNode(x: any): boolean
435
isSymbolNode(x: any): boolean
436
isConstantNode(x: any): boolean
437
isFunctionNode(x: any): boolean
438
isOperatorNode(x: any): boolean
439
// ... and many more node type checks
440
```
441
{ .api }
442
443
```typescript
444
const node = parse('x + 1')
445
isNode(node) // true
446
isOperatorNode(node) // true (+ operator)
447
isSymbolNode(node.args[0]) // true (x symbol)
448
isConstantNode(node.args[1]) // true (1 constant)
449
```
450
451
## Type Conversion and Utilities
452
453
### Generic Type Information
454
455
```typescript
456
typeOf(x: any): string
457
```
458
{ .api }
459
460
```typescript
461
// Get type name
462
typeOf(5) // 'number'
463
typeOf(bignumber('5')) // 'BigNumber'
464
typeOf(complex(1, 2)) // 'Complex'
465
typeOf(fraction(1, 2)) // 'Fraction'
466
typeOf(unit('5 m')) // 'Unit'
467
typeOf(matrix([1, 2])) // 'Matrix'
468
typeOf([1, 2, 3]) // 'Array'
469
typeOf('hello') // 'string'
470
typeOf(true) // 'boolean'
471
typeOf(null) // 'null'
472
typeOf(undefined) // 'undefined'
473
474
// Use for runtime type dispatch
475
function processValue(x) {
476
switch (typeOf(x)) {
477
case 'number': return x * 2
478
case 'BigNumber': return x.times(2)
479
case 'Complex': return multiply(x, 2)
480
case 'string': return x + x
481
default: throw new Error(`Unsupported type: ${typeOf(x)}`)
482
}
483
}
484
```
485
486
### Deep Cloning
487
488
```typescript
489
clone(x: any): any
490
```
491
{ .api }
492
493
```typescript
494
// Deep clone objects and values
495
const original = {
496
num: 5,
497
big: bignumber('123.456'),
498
matrix: matrix([[1, 2], [3, 4]]),
499
nested: { a: 1, b: [2, 3] }
500
}
501
502
const copy = clone(original)
503
copy.matrix.set([0, 0], 99) // Modifying copy doesn't affect original
504
505
// Clone preserves types
506
typeOf(clone(bignumber('5'))) // 'BigNumber'
507
typeOf(clone(complex(1, 2))) // 'Complex'
508
```
509
510
### Numeric Type Conversion
511
512
```typescript
513
numeric(value: MathType, outputType: string): MathType
514
```
515
{ .api }
516
517
```typescript
518
// Convert between numeric types
519
numeric(5, 'BigNumber') // BigNumber(5)
520
numeric('3.14', 'number') // 3.14
521
numeric(bignumber('123'), 'bigint') // 123n
522
numeric(fraction(1, 2), 'number') // 0.5
523
524
// Preserve precision when possible
525
numeric(bignumber('123.456789'), 'Fraction') // Fraction representing exact decimal
526
numeric('0.1', 'BigNumber') // BigNumber(0.1) - no precision loss
527
```
528
529
## Advanced Type System Features
530
531
### Configurable Default Types
532
533
```typescript
534
// Configure Math.js to use different default types
535
import { create, all } from 'mathjs'
536
537
// Use BigNumbers by default
538
const mathBig = create(all, {
539
number: 'BigNumber',
540
precision: 64
541
})
542
543
mathBig.evaluate('0.1 + 0.2') // BigNumber(0.3) - exact
544
mathBig.add(0.1, 0.2) // BigNumber(0.3)
545
546
// Use fractions by default
547
const mathFrac = create(all, {
548
number: 'Fraction'
549
})
550
551
mathFrac.evaluate('1/3 + 1/6') // Fraction(1/2) - exact
552
```
553
554
### Type Coercion Rules
555
556
```typescript
557
// Math.js follows specific type coercion rules:
558
559
// 1. Operations preserve the "highest" precision type
560
add(5, bignumber('2')) // BigNumber(7) - bignumber wins
561
multiply(fraction(1, 2), 3) // Fraction(3/2) - fraction wins
562
add(2, complex(3, 4)) // Complex(5, 4) - complex wins
563
564
// 2. Unit operations require compatible dimensions
565
add(unit('5 m'), unit('3 ft')) // 5.9144 meter (auto-conversion)
566
multiply(unit('5 m'), unit('3 s')) // 15 m*s (compound unit)
567
568
// 3. Matrix operations work element-wise with type promotion
569
const A = matrix([[1, 2]])
570
const B = matrix([[bignumber('3'), bignumber('4')]])
571
add(A, B) // Matrix with BigNumber elements
572
```
573
574
### Custom Type Extensions
575
576
```typescript
577
// Extend Math.js with custom types (advanced)
578
import { create, factory } from 'mathjs'
579
580
// Example: Custom Rational type (simplified)
581
class Rational {
582
constructor(num, den = 1) {
583
this.num = num
584
this.den = den
585
}
586
587
toString() {
588
return `${this.num}/${this.den}`
589
}
590
}
591
592
// Create factory for custom type
593
const createRational = factory('rational', [], () => {
594
return function rational(num, den) {
595
return new Rational(num, den)
596
}
597
})
598
599
// Register with Math.js
600
const math = create({
601
createRational,
602
// ... other dependencies
603
})
604
```
605
606
## Type Validation and Error Handling
607
608
### Input Validation
609
610
```typescript
611
function validateNumeric(value, allowedTypes = ['number', 'BigNumber']) {
612
const type = typeOf(value)
613
if (!allowedTypes.includes(type)) {
614
throw new TypeError(`Expected ${allowedTypes.join(' or ')}, got ${type}`)
615
}
616
return value
617
}
618
619
function safeConvert(value, targetType) {
620
try {
621
return numeric(value, targetType)
622
} catch (error) {
623
console.warn(`Cannot convert ${typeOf(value)} to ${targetType}`)
624
return value // Return original on failure
625
}
626
}
627
```
628
629
### Type-Safe Operations
630
631
```typescript
632
// Ensure compatible types for operations
633
function safeAdd(a, b) {
634
// Convert to common type if possible
635
if (typeOf(a) !== typeOf(b)) {
636
try {
637
if (isNumber(a) && isBigNumber(b)) {
638
a = bignumber(a)
639
} else if (isBigNumber(a) && isNumber(b)) {
640
b = bignumber(b)
641
}
642
} catch (error) {
643
throw new TypeError(`Cannot add ${typeOf(a)} and ${typeOf(b)}`)
644
}
645
}
646
647
return add(a, b)
648
}
649
650
// Type guards for specific operations
651
function requiresInteger(value) {
652
if (!isInteger(value)) {
653
throw new TypeError(`Expected integer, got ${typeOf(value)}`)
654
}
655
}
656
657
function requiresReal(value) {
658
if (isComplex(value) && im(value) !== 0) {
659
throw new TypeError('Complex numbers with non-zero imaginary part not allowed')
660
}
661
}
662
```
663
664
## Performance Considerations
665
666
### Type Selection for Performance
667
668
```typescript
669
// Performance hierarchy (fastest to slowest):
670
// 1. JavaScript number - fastest for small numbers
671
// 2. BigInt - fast for large integers
672
// 3. Complex - overhead for real/imaginary parts
673
// 4. BigNumber - arbitrary precision overhead
674
// 5. Fraction - rational arithmetic overhead
675
// 6. Unit - dimension checking overhead
676
677
// Choose appropriate type for your use case:
678
const fastCalc = 5 + 3 // JavaScript number: fastest
679
const preciseCalc = bignumber('5').plus('3') // BigNumber: precise
680
const integerCalc = 5n + 3n // BigInt: large integers
681
const exactCalc = add(fraction(1,3), fraction(1,6)) // Fraction: exact rationals
682
```
683
684
### Memory Usage
685
686
```typescript
687
// Memory usage considerations:
688
const numbers = Array(1000000).fill().map((_, i) => i) // ~8MB (numbers)
689
const bigNumbers = numbers.map(bignumber) // ~40MB+ (BigNumbers)
690
const complexNumbers = numbers.map(x => complex(x, 0)) // ~24MB+ (Complex)
691
692
// Use appropriate precision
693
const math64 = create(all, { precision: 64 }) // High precision
694
const math16 = create(all, { precision: 16 }) // Lower precision, less memory
695
```
696
697
### Type Conversion Costs
698
699
```typescript
700
// Minimize unnecessary conversions
701
const big1 = bignumber('123')
702
const big2 = bignumber('456')
703
704
// Efficient: stay in same type
705
const result1 = big1.plus(big2) // Fast BigNumber operation
706
707
// Inefficient: multiple conversions
708
const result2 = add(number(big1), number(big2)) // Convert to number, lose precision
709
const result3 = bignumber(result2) // Convert back to BigNumber
710
711
// Better: use Math.js functions that preserve types
712
const result4 = add(big1, big2) // Automatic type handling
713
```
714
715
## Common Type Patterns
716
717
### Working with Mixed-Type Data
718
719
```typescript
720
// Normalize array to common type
721
function normalizeToType(array, targetType) {
722
return array.map(x => numeric(x, targetType))
723
}
724
725
const mixedData = [1, bignumber('2'), fraction(3, 1), '4']
726
const normalized = normalizeToType(mixedData, 'BigNumber')
727
// All BigNumber elements
728
729
// Find "highest" type in array
730
function getHighestType(array) {
731
const typeHierarchy = ['number', 'BigNumber', 'Fraction', 'Complex']
732
let highest = 'number'
733
734
array.forEach(value => {
735
const valueType = typeOf(value)
736
if (typeHierarchy.indexOf(valueType) > typeHierarchy.indexOf(highest)) {
737
highest = valueType
738
}
739
})
740
741
return highest
742
}
743
```
744
745
### Type-Preserving Operations
746
747
```typescript
748
// Ensure operations preserve input type characteristics
749
function preservingAdd(a, b) {
750
const resultType = typeOf(a) === typeOf(b) ? typeOf(a) : 'number'
751
const result = add(a, b)
752
753
// Convert result back to expected type if needed
754
if (typeOf(result) !== resultType) {
755
return numeric(result, resultType)
756
}
757
758
return result
759
}
760
761
// Batch operations with type consistency
762
function sumArray(array) {
763
if (array.length === 0) return 0
764
765
const firstType = typeOf(array[0])
766
return array.reduce((sum, value) => {
767
// Ensure all values are same type as first
768
const normalizedValue = typeOf(value) === firstType ?
769
value : numeric(value, firstType)
770
return add(sum, normalizedValue)
771
})
772
}
773
```
774
775
### Chain Operations with Types
776
777
```typescript
778
// Type information is preserved through chain operations
779
const result = chain(bignumber('123.456'))
780
.add(bignumber('0.544')) // BigNumber arithmetic
781
.multiply(2) // Mixed operation
782
.divide(bignumber('3')) // Back to BigNumber
783
.done() // Result is BigNumber
784
785
typeOf(result) // 'BigNumber'
786
787
// Unit chains preserve dimensions
788
const physics = chain(unit('10 m'))
789
.multiply(unit('5 m')) // 50 m^2
790
.divide(unit('2 s')) // 25 m^2/s
791
.multiply(unit('3 s')) // 75 m^2
792
.done()
793
794
unit.dimensions // Area (length^2)
795
```