Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOCS] Improve docs about callable property #7790

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 55 additions & 10 deletions website/en/docs/types/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,24 +299,69 @@ foo([]);

### Callable Objects <a class="toc" id="toc-callable-objects" href="#toc-callable-objects"></a>

Callable objects can be typed, for example:
You can annotate functions as callable objects, i.e.,

```js
type CallableObj = {
(number, number): number,
bar: string
type F = {
(): string,
};

function add(x, y) {
return x + y;
const f: F = () => 'hello';
```

A function or a callable object may have multiple callable properties, also known as _overloading_.

Note that a few syntax are supported when annotating callable properties:

```js
type F = {
(): string,
(x: boolean): string,
[[call]](x: number): string,
[[call]]: string => string,
};

// It will be fine when a function satisfies them all
const f: F = (x?: boolean | number | string) => {
return x ? x.toString() : '';
}

// $ExpectError
(add: CallableObj);
// And Flow will notice when the function doesn't satisfy them all
const g: F = (x?: number | string) => { // $ExpectError
return x ? x.toString() : '';
}
```

Callable objects can be viewed equivalently as functions with static fields. Function type statics are initially `{}`. Flow will notice when you annotate a variable as function type and try to access its statics without annotation.

add.bar = "hello world";
```js
type F = () => void;

const f: F = () => {
f.foo = 'bar'; // $ExpectError "missing in statics of function type"
}
```

You can annotate function with statics as objects with callable fields. This can be useful when annotating a memoized function:

(add: CallableObj);
```js
type MemoizedFactorial = {
cache: {
[number]: number,
},
[[call]](number): number,
}

const factorial: MemoizedFactorial = n => {
if (!factorial.cache) {
factorial.cache = {}
}
if (factorial.cache[n] !== undefined) {
return factorial.cache[n]
}
factorial.cache[n] = n === 0 ? 1 : n * factorial(n - 1)
return factorial.cache[n]
}
```

### `Function` Type <a class="toc" id="toc-function-type" href="#toc-function-type"></a>
Expand Down