Reputation: 27286
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):
function foo(a: number = 42): number {return a+1;}
type FooT= (a: number)=> number
(foo: FooT)
foo();
(try it here)
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
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