josdejong/mathjs

typeOf() does not remain consistent with typed-function types

Open

#3,376 opened on Feb 1, 2025

View on GitHub
 (2 comments) (0 reactions) (0 assignees)JavaScript (13,832 stars) (1,298 forks)batch import
bughelp wanted

Description

Describe the bug The typed-function typing system is centrally used, for example in defining and extending most of the methods mathjs provides. However, the typeOf method that mathjs provides bypasses the typed-function type system altogether, trying to determine the type of the object in its own way that is not necessarily consistent with typed-function's notion of the type of the entity.

To Reproduce There are many possibly ways this can come up, but the simplest is by adding a typed-function type with a non-standard type test. Here's a toy example:

import {all, create} from 'mathjs'
const math = create(all)

math.typed.addTypes([{
    name: 'Negative',
    test: x => typeof x === 'number' && x < 0
}], 'number') // specify the new types are added _before_ number in the hierarchy

math.import({
    sqRt: math.typed('sqRt', {
        Negative: () => 'Sorry charlie',
        number: x => Math.sqrt(x)
    })
})

console.log(math.evaluate('[sqRt(-4), sqRt(4), typeOf(-4)].valueOf()'))

This prints [ 'Sorry charlie', 2, 'number' ] showing that the type definition worked and that functions can use it but that mathjs does not realize that -4 is now of type Negative. While this example is a bit frivolous, it can come up in more reasonable contexts: structured plain object types that mathjs then identifies as just Object when I want to know that they are a Polar object, or that sort of thing.

Recommendation typed-function has an unexported method findTypeNames that determines all of the matching types for an entity. typed-function should be updated to export this method, and mathjs typeOf should simply return the first (most specific) element of this list.

Contributor guide