Skip to content

Commit

Permalink
fix: #2919 TypeScript types not working with NodeNext module resoluti…
Browse files Browse the repository at this point in the history
…on (#3079)
  • Loading branch information
josdejong authored Oct 26, 2023
1 parent 3030c6b commit 544b86f
Show file tree
Hide file tree
Showing 5 changed files with 6,855 additions and 6,492 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ A common case is to implement a new function. This involves the following steps:
- Write documentation on the function in the source code comment of `myNewFunction.js`. This documentation is used to auto generate documentation on the website.
- Write embedded documentation for the new function in `./src/expression/embeddedDocs/function/arithmetic/myNewFunction.js`. Add the new documentation to the index file `./src/expression/embeddedDocs/embeddedDocs.js`.
- Write unit tests for the function in `./test/unit-tests/function/arithmetic/myNewFunction.test.js`.
- Write a TypeScript definition for the new function in `./types/index.d.ts`, and write tests for it in `./types/index.ts`. Normally, two definitions need to be added: one for the static function `math.myNewFunction(...)` and one for the chained API `math.chain(...).myNewFunction(...)`.
- Write the necessary TypeScript definitions for the new function in `./types/index.d.ts`, and write tests for it in `./test/typescript-tests/testTypes.ts`. This is described in [./types/EXPLANATION.md](./types/EXPLANATION.md).
- Ensure the code style is ok by running `npm run lint` (run `npm run format` to fix the code style automatically).


Expand Down
2 changes: 1 addition & 1 deletion test/typescript-tests/testTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1987,7 +1987,7 @@ Extend functionality with import
*/

declare module 'mathjs' {
interface MathJsStatic {
interface MathJsInstance {
testFun(): number
value: number
}
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"paths": {
"mathjs": ["./types/index.d.ts"]
},
"moduleResolution": "node",
"moduleResolution": "nodenext",
"typeRoots": [],
"types": [],
"lib": ["ES6", "DOM"],
"module": "ESNEXT",
"module": "NodeNext",
"noEmit": true,
"noImplicitAny": true,
"noImplicitThis": true,
Expand Down
54 changes: 54 additions & 0 deletions types/EXPLANATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Mathjs TypeScript types

The code base of Mathjs is writting in JavaScript. The TypeScript definitions are maintained separately.

## Library structure

The over all structure is:

- The library exports the core function `create` which creates a MathJS instance and returns `MathJsInstance`.
- Mathjs has a special function `chain`, which allows you to use the functions in a chained way, like `chain(2).add(3).done()`. The function `chain` returns an interface `MathJsChain`, which contains all mathjs functions and constants as a method. Unlike the static functions, these methods are defined with the chain instance `this` as first argument.
- The library exports collections with factory functions of all functions and their dependencies. To create an instance of the function `add`, one can do `create(addDependencies)` for example. To import all functions, one can do `create(all)`.
- The library also returns a static instance, which can directly be used like `import { add } from 'mathjs'`.

## Defining the types of a new function

Maintaining the TypeScript types is done manually. When adding a function, one has to create the following TypeScript definitions:

1. Add a normal definition inside `interface MathJsInstance {...}`
2. Add a chained definition inside `interface MathJsChain {...}`
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:

```ts
// instance
export interface MathJsInstance extends MathJsFactory {
//...
add<T extends MathType>(x: T, y: T): T
//...
}

// chain
export interface MathJsChain<TValue> {
//...
add<T extends MathType>(this: MathJsChain<T>, y: T): MathJsChain<T>
//...
}

// static
export const {
// ...
add,
// ...
} : MathJsInstance


// dependencies
export const {
// ...
addDependencies,
// ...
} : Record<string, FactoryFunctionMap>
```
Loading

0 comments on commit 544b86f

Please sign in to comment.