fix: #3493 #3499 #3494 type definitions of unit(number), for add and multiply without arguments, and for unit.to(unit) (#3495)

* fixes #3493 allowing math.unit(5), which would now fail because for values of MathNumericType and MathCollection, the second parameter wasn't optional

* Added tests, and as a result of that, fixed the definition of unit(value: MathCollection): Unit[] where no units seem to be allowed

* Changes as requested by josdejong

* math.add and math.multipl type fixes and added tests

* fixes #3494: math.unit(m).to(math.unit(cm)) is now ok for typescript
This commit is contained in:
mrft 2025-07-02 10:37:44 +02:00 committed by GitHub
parent caa67e887a
commit 09f6da9278
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 10 deletions

View File

@ -267,5 +267,6 @@ Delaney Sylvans <delaneysylvans@gmail.com>
Rani D. <73716554+ranidam@users.noreply.github.com>
Don McCurdy <dm@donmccurdy.com>
Jay Chang <96050090+JayChang4w@users.noreply.github.com>
Frederik Tilkin <977655+mrft@users.noreply.github.com>
# Generated by tools/update-authors.js

View File

@ -86,8 +86,29 @@ Basic usage examples
math.add(math.pow(math.sin(angle), 2), math.pow(math.cos(angle), 2))
math.add(2, 3, 4)
math.add(2, 3, math.bignumber(4))
// @ts-expect-error: string arguments are not supported by the types, but it works (if the string contains a number)
math.add(2, '3')
// @ts-expect-error: string arguments are not supported by the types, but it works (if the string contains a number), but should throw an error if it is something else
assert.throws(() => math.add(2, '3 + 5'))
// @ts-expect-error: string arguments are not supported by the types, but it works (if the string contains a number), but should throw an error if it is something else
assert.throws(() => math.add(2, '3 cm'))
// @ts-expect-error: no arguments are not supported by the types, and should throw an error
assert.throws(() => math.add())
// @ts-expect-error: 1 argument is not supported by the types, and should throw an error
assert.throws(() => math.add(1))
math.multiply(2, 3, 4)
math.multiply(2, 3, math.bignumber(4))
// @ts-expect-error: string arguments are not supported by the types, but it works (if the string contains a number)
math.multiply(2, '2') // currently not supported by the types, but turns out to work
// @ts-expect-error: string arguments are not supported by the types, but it works (if the string contains a number), but should throw an error if it is something else
assert.throws(() => math.multiply(2, '3 + 5'))
// @ts-expect-error: string arguments are not supported by the types, but it works (if the string contains a number), but should throw an error if it is something else
assert.throws(() => math.multiply(2, '3 cm'))
// @ts-expect-error: no arguments are not supported by the types, and should throw an error
assert.throws(() => math.multiply())
// @ts-expect-error: 1 argument is not supported by the types, and should throw an error
assert.throws(() => math.multiply(1))
// std and variance check
@ -1741,6 +1762,35 @@ Units examples
{
const math = create(all, {})
/*
Unit function type tests
*/
{
// Test unit function with string argument
expectTypeOf(math.unit('5 cm')).toExtend<Unit>()
// Test unit function with Unit argument
expectTypeOf(math.unit(math.unit('5 cm'))).toExtend<Unit>()
// Test unit function with MathNumericType and string
expectTypeOf(math.unit(5, 'cm')).toExtend<Unit>()
expectTypeOf(math.unit(math.bignumber(5), 'cm')).toExtend<Unit>()
expectTypeOf(math.unit(math.fraction(5, 2), 'cm')).toExtend<Unit>()
expectTypeOf(math.unit(math.complex(5, 0), 'cm')).toExtend<Unit>()
// Test unit function with just MathNumericType (optional unit parameter)
expectTypeOf(math.unit(5)).toExtend<Unit>()
expectTypeOf(math.unit(math.bignumber(5))).toExtend<Unit>()
expectTypeOf(math.unit(math.fraction(5, 2))).toExtend<Unit>()
// Shouldn't this also work? Currently it does not.
// expectTypeOf(math.unit(math.complex(5, 0))).toExtend<Unit>()
// Test unit function with just MathCollection
expectTypeOf(math.unit(math.matrix([1, 2, 3]))).toExtend<Unit[]>()
expectTypeOf(math.unit([1, 2, 3])).toExtend<Unit[]>()
expectTypeOf(math.unit(math.matrix(['2cm', '5cm']))).toExtend<Unit[]>()
}
// units can be created by providing a value and unit name, or by providing
// a string with a valued unit.
const a = math.unit(45, 'cm') // 450 mm
@ -1803,6 +1853,7 @@ Units examples
// units can be converted to a specific type, or to a number
b.to('cm')
b.to(math.unit('m'))
math.to(b, 'inch')
b.toNumber('cm')
math.number(b, 'cm')

View File

@ -20,7 +20,7 @@ Maintaining the TypeScript types is done manually. When adding a function, one h
3. Add a static definition inside `export const {...} : MathJsInstance`
4. Add a dependencies definition inside `export const {...} : Record<string, FactoryFunctionMap>`
For exampe for the function `add`, we can have the following definitions:
For example for the function `add`, we can have the following definitions:
```ts
// instance

17
types/index.d.ts vendored
View File

@ -867,8 +867,8 @@ export interface MathJsInstance extends MathJsFactory {
* @param unit The unit to be created
* @returns The created unit
*/
unit(value: MathNumericType, unit: string): Unit
unit(value: MathCollection, unit: string): Unit[]
unit(value: MathNumericType, unit?: string): Unit
unit(value: MathCollection): Unit[]
/*************************************************************************
* Expression functions
@ -1136,9 +1136,9 @@ export interface MathJsInstance extends MathJsFactory {
* @returns Sum of x and y
*/
add<T extends MathType>(x: T, y: T): T
add<T extends MathType>(...values: T[]): T
add<T extends MathType>(x: T, y: T, ...values: T[]): T
add(x: MathType, y: MathType): MathType
add(...values: MathType[]): MathType
add(x: MathType, y: MathType, ...values: MathType[]): MathType
/**
* Calculate the cubic root of a value.
@ -1465,9 +1465,8 @@ export interface MathJsInstance extends MathJsFactory {
multiply<T extends MathArray>(x: T, y: T): MathScalarType
multiply(x: Unit, y: Unit): Unit
multiply(x: number, y: number): number
multiply(x: MathType, y: MathType): MathType
multiply<T extends MathType>(...values: T[]): T
multiply(...values: MathType[]): MathType
multiply(x: MathType, y: MathType, ...values: MathType[]): MathType
multiply<T extends MathType>(x: T, y: T, ...values: T[]): T
/**
* Calculate the norm of a number, vector or matrix. The second
@ -4177,7 +4176,7 @@ export interface Unit {
divide(unit: Unit): Unit | number
pow(unit: Unit): Unit
abs(unit: Unit): Unit
to(unit: string): Unit
to(unit: string | Unit): Unit
toNumber(unit?: string): number
toNumeric(unit?: string): number | Fraction | BigNumber
toSI(): Unit
@ -4827,7 +4826,7 @@ export interface MathJsChain<TValue> {
*/
unit(this: MathJsChain<string>, unit?: string): MathJsChain<Unit>
unit(this: MathJsChain<MathNumericType>, unit?: string): MathJsChain<Unit>
unit(this: MathJsChain<MathCollection>, unit?: string): MathJsChain<Unit[]>
unit(this: MathJsChain<MathCollection>): MathJsChain<Unit[]>
/*************************************************************************
* Expression functions