You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add function statics and object callable properties (#55)
* Add function statics and object callable properties
* Update function statics and object callables
- Use simpler examples
- Add TypeScript on object callables
* Add TypeScript example for overloading callable
* Updates on callable properties
* Updates on callable properties
- Move to "same syntax"
- Add a few library definitions as reference
* Add back the line # Read-only Types that got deleted by accident
* Not sure how TS supports function statics
* Resolve PR discussion and add function statics
Copy file name to clipboardExpand all lines: README.md
+118Lines changed: 118 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -519,6 +519,8 @@ add("1", "1"); // Ok
519
519
add(1, "1"); // Error
520
520
```
521
521
522
+
It is also possible to create function overloads using callable property syntax, see the section [Object callable property](#object-callable-property).
523
+
522
524
### TypeScript
523
525
524
526
TypeScript supports both function and method overloading, in both: type definitions (`.d.ts`) and inline alongside code.
@@ -635,6 +637,122 @@ However, Flow implementation is stricter in this case, as B have a property that
635
637
636
638
Most of the syntax of Flow and TypeScript is the same. TypeScript is more expressive for certain use-cases (advanced mapped types with keysof, readonly properties), and Flow is more expressive for others (e.g. `$Diff`).
637
639
640
+
## Object callable property
641
+
642
+
The basic syntax are the same, except Flow has special syntax for the internal call property slot.
643
+
644
+
Both can be used to annotate function statics.
645
+
646
+
### Flow
647
+
648
+
You can use objects with callable properties as functions: [Try Flow](https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1AMVALygDeiooAFAJQBcoAzigE4CWAdgOaIC+A3IgGNYbRqEh18RaoQB8oAEQALLNDjz+QkSlDLVsOo1adCY6ryA)
649
+
650
+
```js
651
+
type F= {
652
+
(): string
653
+
};
654
+
const f:F= () =>"hello";
655
+
const hello:string=f();
656
+
```
657
+
658
+
An overloaded function is a function with multiple call signatures.
659
+
This is supported by Flow. And we list out the different syntaxes here: [Try Flow](https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1AMVALygDeiooAFAJQBcoAzigE4CWAdgOYA0ZoA2nwDGAQ2jQAuuLoU2AVwC2AIyxMqhAHwNm7brwEixkio1adaW0x0QBfZINhtGoSHXxEKADwD8dOUpWgAD4WOmoEmqTkTFgoskxsoB6gXokAdCiwAMranNSgdADkBQDcNohAA)
660
+
661
+
```js
662
+
type F= {
663
+
(): string,
664
+
[[call]]: (number) => string,
665
+
[[call]](string): string
666
+
}
667
+
668
+
const f:F= (x?:number|string) => {
669
+
return x ?x.toString() :'';
670
+
}
671
+
```
672
+
673
+
Use call property to annotate function statics: [Try Flow](https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1AWSwLawCWAXlgCYBiAhgMYqwBOxN0AKpjgLygDeiUKDr0AFlgBc-QaACQAbQB2AVwIAjLEwC6Ules0yAvgBoZ8+SOjQtWgBR6NTAJS7Vj04eR1YigM4pQSHpGFjYpfCIySloGZlYOLlBeRSSAPmkhYkhQWwBCINjQ6AA6ETpxJwyhQOC4tlKxHn5PIRbQLJyCkPiG8qwlLVBc7l5lRQosSGJFSkqBatAmLBRlJhSuupKy8QGjGQ2i3p3FQeSkkdAABlAAflAARlBdUAAqGsL4+1AAWgenGSWKzW7269W2-ROiEMQA)
-[immer.js](https://github.com/immerjs/immer/blob/master/src/immer.js.flow) uses it to overload the `produce` (default export) function which has multiple call signatures
699
+
-[Styled Components](https://github.com/flow-typed/flow-typed/blob/master/definitions/npm/styled-components_v4.x.x/flow_v0.75.x-/styled-components_v4.x.x.js#L242) uses it to separate cases of being called on a string and wrapping a component
700
+
-[Reselect Library Definition](https://github.com/flow-typed/flow-typed/blob/master/definitions/npm/re-reselect_v2.x.x/flow_v0.67.1-/re-reselect_v2.x.x.js) contains massive chunks of overloaded call properties
701
+
702
+
### TypeScript
703
+
704
+
You can use objects with callable properties as functions: [TypeScript Playground](https://www.typescriptlang.org/play/#src=type%20F%20%3D%20%7B%0D%0A%20%20()%3A%20string%3B%0D%0A%7D%0D%0Aconst%20foo%3A%20F%20%3D%20()%20%3D%3E%20%22hello%22%3B%0D%0Aconst%20bar%3A%20string%20%3D%20foo()%3B)
705
+
706
+
```ts
707
+
typeF= {
708
+
():string;
709
+
}
710
+
const foo:F= () =>"hello";
711
+
const bar:string=foo();
712
+
```
713
+
714
+
An overloaded function is a function with multiple call signatures.
715
+
This is also supported by TypeScript: [TypeScript Playground](https://www.typescriptlang.org/play/#src=type%20F%20%3D%20%7B%0D%0A%20%20()%3A%20string%2C%0D%0A%20%20(number)%3A%20string%2C%0D%0A%20%20(string)%3A%20string%0D%0A%7D%0D%0A%0D%0Aconst%20f%3A%20F%20%3D%20(x%3F%3A%20number%20%7C%20string)%20%3D%3E%20%7B%0D%0A%20%20return%20x%20%3F%20x.toString()%20%3A%20''%3B%0D%0A%7D%0D%0A)
716
+
717
+
718
+
```ts
719
+
typeF= {
720
+
():string,
721
+
(x:number):string,
722
+
(x:string):string
723
+
}
724
+
725
+
const f:F= (x?:number|string) => {
726
+
returnx?x.toString() :'';
727
+
}
728
+
```
729
+
730
+
Use call property to annotate function statics: [TypeScript Playground](https://www.typescriptlang.org/play/#src=type%20MemoizedFactorialType%20%3D%20%7B%0D%0A%20%20cache%3F%3A%20%7B%0D%0A%20%20%20%20%5Bn%3A%20number%5D%3A%20number%2C%0D%0A%20%20%7D%2C%0D%0A%20%20(n%3A%20number)%3A%20number%2C%0D%0A%7D%0D%0A%0D%0Aconst%20factorial%3A%20MemoizedFactorialType%20%3D%20n%20%3D%3E%20%7B%0D%0A%20%20if%20(!factorial.cache)%20%7B%0D%0A%20%20%20%20factorial.cache%20%3D%20%7B%7D%0D%0A%20%20%7D%0D%0A%20%20else%20if%20(factorial.cache%5Bn%5D%20!%3D%3D%20undefined)%20%7B%0D%0A%20%20%20%20return%20factorial.cache%5Bn%5D%0D%0A%20%20%7D%0D%0A%20%20factorial.cache%5Bn%5D%20%3D%20n%20%3D%3D%3D%200%20%3F%201%20%3A%20n%20*%20factorial(n%20-%201)%0D%0A%20%20return%20factorial.cache%5Bn%5D%0D%0A%7D)
731
+
732
+
```ts
733
+
typeMemoizedFactorialType= {
734
+
cache?: {
735
+
[n:number]:number,
736
+
},
737
+
(n:number):number,
738
+
}
739
+
740
+
const factorial:MemoizedFactorialType=n=> {
741
+
if (!factorial.cache) {
742
+
factorial.cache= {}
743
+
}
744
+
elseif (factorial.cache[n] !==undefined) {
745
+
returnfactorial.cache[n]
746
+
}
747
+
factorial.cache[n] =n===0?1:n*factorial(n-1)
748
+
returnfactorial.cache[n]
749
+
}
750
+
```
751
+
752
+
Reference:
753
+
-[Callable on TypeScript Book](https://github.com/basarat/typescript-book/blob/master/docs/types/callable.md)
0 commit comments