josdejong / josdejong/mathjs

`OperatorNode` type should accept generics for 'op' and 'fn'

Open
#2,575 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
15.1k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

# The Problem

Right now all operator types share the same basic `OperatorNode` type. This has a few consequences:
- Nothing right now prevents creating invalid operators (like I did the other day) with `new OperatorNode('*', 'mult')`
- Right now you can't properly use multiple subsequent type guards that all check for a diff operator type

For example, say I've defined my own custom type guards like so

```ts
export function isAdditionNode(node: MathNode): node is OperatorNode {
return isOperatorNode(node) && node.fn === 'add'
}

export function isSubtractionNode(node: MathNode): node is OperatorNode {
return isOperatorNode(node) && node.fn === 'subtract'
}
```

If I try to then use them like this

```ts
function doStuff(node: MathNode) {
if (isAdditionNode(node)) {
return node.args[0]
}
if (isSubtractionNode(node)) {
return node.args[0]
}
}
```

Typescript is sad and upset because it thinks that the first type guard should have caught _any_ operator node and therefore you could never have the second case (explaining the `never` type)

image

# The Solution

If we added generic args to OperatorNode for `op` and `fn` typescript would warn us when making invalid operator nodes

image

and would allow doing this with type guards:

```ts
export function isAdditionNode(node: MathNode): node is OperatorNode<'+', 'add'> {
return isOperatorNode(node) && node.fn === 'add'
}

export function isSubtractionNode(node: MathNode): node is OperatorNode<'-', 'subtract'> {
return isOperatorNode(node) && node.fn === 'subtract'
}
```

Which then makes typescript very happy 🌈

image

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.