Flow: Why are argument names needed in function type definitions?

Created on 15 Aug 2016  路  3Comments  路  Source: facebook/flow

This might have been discussed in the past; but is there a reason why argument names are needed in function type definitions?
E.g. f: (x: T) => U as opposed to f: T => U.

The latter form is commonly used in other languages such as Scala. The argument names feel redundant and usually make the code less readable, e.g.:

const myFunction: (arg: string) => string = arg => { // implementation }
Needs docs

All 3 comments

It's a design decision borrowed from TypeScript. Curiously the intent is to _improve_ readability. For example you might have a two-param function both needing string, one for name and the other for address, and naming things helps callers pass the arguments in the right order.

Interesting. Argument names are not type checked though, i.e. in your example if I change the order of name and address arguments in the function which is passed in, but forget to change the order in the caller, flowtype won't warn me. So I wonder if making them a mandatory part of a function type signature is necessary.

There are alternatives to making it clearer (documenting) what each argument is if the arguments for a function happen to be of the same type:

1- Using type aliases, e.g.:

type Name = string;
type Address = string;
const myFunction: (Name, Address) => SomeOtherType = (name, address) => // implementation

2- Wrapping arguments in an object:

type Name = string;
type Address = string;
const myFunction: ( { name: string; address: string } ) => SomeOtherType = ( { name, address } ) => // implementation

Given that, would there be an appetite for supporting function type signatures without the need for naming arguments, alongside the current format?

If there is, I don't mind trying to implement this (haven't played with OCaml before, but would be a good learning experience for me).

One option is to define a series of generic Fn types

type Fn0<A> = () => A;
type Fn1<A, B> = (a: A) => B;
type Fn2<A, B, C> = (a: A, b: B) => C;
type Fn3<A, B, C, D> = (a: A, b: B, c: C) => D;
// etc...

const myFunction: Fn1<string, string> // string -> string
  = arg => {
    // implementation
  }
Was this page helpful?
0 / 5 - 0 ratings