I am trying to write a Javascript project with strict flow typing everywhere. I also have a dependency on big-integer
. There are no preset flow annotations in flow-typed
unfortunately and Google is not supplying anything useful on the topic.
Like a lot of JavaScript packages, big-integer
exports a single function, which is usually called bigInt
. This can be called directly, like so: bigInt(13)
, bigInt("134e134")
, etc., which creates objects which are big integers (I've decided to call the type of the return value of this function a "class" called "BigInteger" based on the documentation -- but I don't think the internals actually use classes since I believe the package came out before ES6).
This works fine for the output of the function and I can attach methods to that class and we're all good. However, bigInt
itself has some methods, e.g. bigInt.lcm(123, 234)
. How can I document this?
declare module "big-integer-types" {
declare class BigInteger {
add(addend: BigIntInput): BigInteger;
minus(subtractand: BigIntInput): BigInteger;
/* snip */
}
declare type BigIntInput = number | string | BigInteger;
declare type BigIntFn = (void | number | string | BigInteger) => BigInteger;
}
declare module "big-integer" {
import type { BigIntFn } from "big-integer-types";
declare export default BigIntFn
}
This works well for the fields of big integers, e.g. for type-checking bigInt(12).plus("144e53")
. Which is great. But this doesn't include bigInt.lcm(134, 1551)
and that gives a flow error.
The alternative is to declare the export of the big-integer
module to be a type which has certain associated functions. For example:
declare module "big-integer-types" {
declare type BigIntegerStaticMethods {
lcm(a: BigIntInput, b: BigIntInput): BigInteger,
/* snip */
}
declare type BigIntInput = number | string | BigInteger;
}
declare module "big-integer" {
import type BigIntegerStaticMethods from "big-integer-types";
declare export default BigIntegerStaticMethods
}
This works for the static methods, but I don't know how to say a "type" can be called. So I'm at a loss as to how to achieve both at once.
This seems weird because a function with fields is quite common in javascript and the flow documentation suggests they went through a lot of effort to have the type system support javascript as it is used. So I figure there is a flow syntax to achieve this, I just couldn't figure out what it was, and couldn't find it in the docs.