You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Complex numbers are surely numbers, just from a different system. Yet isNumeric and hasNumericValue return false on them. This directly contradicts (for example) the TypeScript type definition MathNumericType = number | BigNumber | Fraction | Complex
isNumeric and hasNumericValue fail on e.g. {a: 1, b: 2}. Surely they should not fail on any inputs. In this particular case, I think the desired return value is 'false'. One could make an argument for {a: true, b: true} by analogy with how Arrays are handled, but I don't think any mathjs functions distribute over object structure in this way.
Whether booleans are isNumeric is very debatable. And the fact it currently returns true contradicts the TypeScript MathNumericType definition, in the opposite direction from Complex. Certainly a boolean hasNumericValue in exactly the same way as a string does, in that they automatically convert to 0 and 1 in any numeric context. But the fact that true * false is 0 rather than false, the same way that "1" * "0" is just 0 not "0" suggests that booleans are not themselves numeric. I would strongly suggest leaving hasNumericValue true for booleans, and either:
making isNumeric false for booleans, or
making * non-short-circuiting and, and + non-short-circuiting or. Then the booleans are exactly a copy of the field of two elements -- definitely numeric. And in this case, add boolean to TypeScript MathNumericType, which should align with isNumeric.
Typescript typing of isNumeric is currently: isNumeric(x: any): x is number | BigNumber | Fraction | boolean. This is wrong in three ways:
isNumeric only accepts (currently a subset of) MathTypes, not truly any value. It could be extended to return false on anything else, in which case the input type is correct (but should be changed to x: unknown to comport with current usage and eliminate the disabling of the any rule); or the typing could be changed to reflect the types it actually takes.
isNumeric is not (at least not currently) a type guard. It does not even always return a boolean value (e.g. on arrays).
Even when isNumeric returns a truthy value, its argument is not necessarily one of the listed types. It could be a bigint, or an Array or a Matrix.
Typescript typing of hasNumericValue should be similar to that for isNumeric and hence might need to be updated when the typing of isNumeric is fixed in some way or another.
Since isNumeric returning a truthy value does not guarantee that its argument is a scalar, mathjs should have an isScalar function that does serve as a type guard. Otherwise, it is difficult to use the result of math.evaluate() in some mathjs functions in typescript.
To Reproduce
math.isNumeric(Complex(1,2)) // returns false, expect true
math.isNumeric(false) // returns true, dubious
math.isNumeric({a: 1, b:2}) // throws TypeError, expect successful return of false
if (math.isNumeric(A)) return A[0] // could be perfectly OK code, but TypeScript reports: error TS7053:
// Element implicitly has an 'any' type because expression of type '0' can't be used to
// index type 'number | BigNumber | Fraction'.
if (math.isNumeric(n)) x = math.cube(n) // No TypeScript error, but is not actually OK; can
// throw a TypeError at runtime if n happens to be [3, 4, 5], say.
return math.isNumeric([3,4,5])[0] // Is perfectly OK, but TypeScript reports: error TS7053 for type Boolean.
The text was updated successfully, but these errors were encountered:
Describe the bug
isNumeric
andhasNumericValue
return false on them. This directly contradicts (for example) the TypeScript type definitionMathNumericType = number | BigNumber | Fraction | Complex
isNumeric
andhasNumericValue
fail on e.g.{a: 1, b: 2}
. Surely they should not fail on any inputs. In this particular case, I think the desired return value is 'false'. One could make an argument for{a: true, b: true}
by analogy with how Arrays are handled, but I don't think any mathjs functions distribute over object structure in this way.isNumeric
is very debatable. And the fact it currently returns true contradicts the TypeScriptMathNumericType
definition, in the opposite direction fromComplex
. Certainly a booleanhasNumericValue
in exactly the same way as a string does, in that they automatically convert to 0 and 1 in any numeric context. But the fact thattrue * false
is0
rather than false, the same way that"1" * "0"
is just0
not"0"
suggests that booleans are not themselves numeric. I would strongly suggest leavinghasNumericValue
true for booleans, and either:isNumeric
false for booleans, or*
non-short-circuitingand
, and+
non-short-circuitingor
. Then the booleans are exactly a copy of the field of two elements -- definitely numeric. And in this case, add boolean to TypeScript MathNumericType, which should align withisNumeric
.isNumeric
is currently:isNumeric(x: any): x is number | BigNumber | Fraction | boolean
. This is wrong in three ways:x: unknown
to comport with current usage and eliminate the disabling of the any rule); or the typing could be changed to reflect the types it actually takes.hasNumericValue
should be similar to that forisNumeric
and hence might need to be updated when the typing ofisNumeric
is fixed in some way or another.isNumeric
returning a truthy value does not guarantee that its argument is a scalar, mathjs should have anisScalar
function that does serve as a type guard. Otherwise, it is difficult to use the result ofmath.evaluate()
in some mathjs functions in typescript.To Reproduce
The text was updated successfully, but these errors were encountered: