Marcus Junius Brutus
Marcus Junius Brutus

Reputation: 27286

type annotation for parameter with default value

In the following function definition:

 function foo(a: number = 42): number {return a+1;}

… what are the semantics of the a: number annotation?

Is it saying that variable a will always have a value inside the body of the function or is it saying that client programmers should always supply a value when they make the call?

I've noticed that both the below code snippets type-check with no errors (with flow-bin 0.57.3):

snippet 1

function foo(a: number = 42): number {return a+1;}
type FooT= (a: number)=> number

(foo: FooT)

foo();

(try it here)

snippet 2

function foo(a: ?number = 42): number {return a+1;}
type FooT = (a: ?number)=> number

(foo: FooT)

foo();

(try it here)

What is the suggested way to annotate in such a case?

My preference is with way #2 as the client programmer only has to look at the definition of the FooT type to realize that the parameter is optional. This allows me to tell users of my library: "simply look at the type of the function (FooT)".

Whereas with way #1 I have to tell them "the type of the function (FooT) seems to suggest that an argument is required, but in fact it isn't because, see, if you look at the implementation, a default value is supplied".

So, which snippet is more idiomatic?

Note that there is an answer to a related question that seems to suggest that it is possible to annotate the type as mandatory in the implementation of a function and as optional in the declaration. But this doesn't seem to work in this case. E.g. the following doesn't type-check:

function foo(a: number = 42): number {return a+1;}
type FooT = (a: ?number)=> number

(foo: FooT)

foo();

(try it here)

Upvotes: 5

Views: 2166

Answers (1)

Aleksey L.
Aleksey L.

Reputation: 37918

You can go with:

function foo(a: number = 42): number {return a+1;}
type FooT = (a?: number)=> number

(foo: FooT)

foo();

Pay attention to ? position in type definition:

(a?: number) - optional parameter

vs

(a: ?number) - maybe type

The only difference between the two is that the optional parameter can't be null, just like a parameter with default value

Upvotes: 7

Related Questions