Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare Flow types for a function which has fields?

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.

like image 558
Richard Rast Avatar asked Dec 24 '17 23:12

Richard Rast


People also ask

Is flow deprecated?

Effective October 2023, all existing flows using the deprecated legacy actions and triggers will cease to work. Users will need to review their existing flows to update them to the new actions and triggers.

What is generic flow?

Generic Flow Control is employed in the header of the ATM (Asynchronous Transfer Mode) cell at the UNI (User to Network Interface) interface. It is used to define a multiplicity of users at a common interface.

What are maybe types?

Maybe types represent values that might be missing. In most languages, a missing value is represented by the null value. By using a context representing a value that might be missing, the Maybe type allows you to write much safer code.

Is flow like TypeScript?

Flow and TypeScript have significantly similar type definition syntaxes. They both: Support JavaScript primitive types and derived (object) types for type checking variables. Have a similar syntax for type annotations.


1 Answers

You can declare an unnamed static function in the class:

declare type BigIntInput = number | string | BigInteger;
declare class BigInteger {
  add(addend: BigIntInput): BigInteger;
  minus(subtractand: BigIntInput): BigInteger;

  static lcm(a: BigIntInput, b: BigIntInput): BigInteger;
  static (data?: BigIntInput): BigInteger;  
} 

BigInteger.lcm(1,2);
BigInteger(4).add(5);
like image 95
user3707125 Avatar answered Oct 05 '22 23:10

user3707125