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
[flow][docs] Trim removed utility types to one-line replacement pointers
Summary:
Replace verbose examples and explanations for removed utility types
($Diff, $Rest, $PropertyType, $ElementType, $TupleMap, $Call, $ObjMap,
$ObjMapi, $ObjMapConst, $Partial, $Shape) with a single sentence each
pointing to the recommended replacement. Anchor IDs are preserved so
existing inbound links (e.g. from indexed-access.md) continue to work.
Changelog: [internal]
Reviewed By: SamChou19815
Differential Revision: D98820006
fbshipit-source-id: 487f9d3c1b9701904cd7071a778371d265368da8
As the name hints, `$Diff<A, B>` is the type representing the set difference of `A` and `B`, i.e. `A \ B`, where `A` and `B` are both [object types](../objects/). Here's an example:
619
-
620
-
```js flow-check
621
-
type Props = {name: string, age: number, ...};
622
-
type DefaultProps = {age: number};
623
-
type RequiredProps = $Diff<Props, DefaultProps>;
624
-
625
-
functionsetProps(props:RequiredProps) {
626
-
// ...
627
-
}
628
-
629
-
setProps({name:'foo'}); // Works
630
-
setProps({name:'foo', age:42, baz:false}); // Works, you can pass extra props too
631
-
setProps({age:42}); // Error! `name` is required
632
-
```
633
-
634
-
As you may have noticed, the example is not a random one.
635
-
`$Diff` is exactly what the React definition file uses to define the type of the props accepted by a React Component.
636
-
637
-
Note that `$Diff<A, B>` will error if the object you are removing properties from does not have the property being removed, i.e. if `B` has a key that doesn't exist in `A`:
638
-
639
-
```js
640
-
type Props = {name: string, age: number};
641
-
type DefaultProps = {age: number, other: string};
642
-
type RequiredProps = $Diff<Props, DefaultProps>; // Error!
643
-
644
-
functionsetProps(props:RequiredProps) {
645
-
props.name;
646
-
// ...
647
-
}
648
-
```
649
-
650
-
As a workaround, you can specify the property not present in `A` as optional. For example:
`$Rest<A, B>` is the type that represents the runtime object rest operation, e.g.: `const {foo, ...rest} = obj`, where `A` and `B` are both [object types](../objects/).
665
-
The resulting type from this operation will be an object type containing `A`'s *own* properties that are not *own* properties in `B`.
666
-
In flow, we treat all properties on [exact object types](../objects/#exact-and-inexact-object-types) as [own](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty).
667
-
For inexact objects, a property may or may not be own.
668
-
669
-
For example:
670
-
671
-
```js
672
-
type Props = {name: string, age: number};
673
-
674
-
const props:Props= {name:'Jon', age:42};
675
-
const {age, ...otherProps} = props;
676
-
otherProps as $Rest<Props, {age: number}>;
677
-
otherProps.age; // Error!
678
-
```
679
-
680
-
The main difference with [`$Diff<A, B>`](#toc-diff), is that `$Rest<A, B>` aims to represent the true runtime rest operation,
681
-
which implies that exact object types are treated differently in `$Rest<A, B>`.
682
-
For example, `$Rest<{n: number}, {...}>` will result in `{n?: number}` because an in-exact empty object may have an `n` property,
683
-
while `$Diff<{n: number}, {...}>` will result in `{n: number}`.
`$TupleMap<T, F>` takes an iterable type `T` (e.g.: [`Tuple`](../tuples) or [`Array`](../arrays)), and a [function type](../functions) `F`,
696
-
and returns the iterable type obtained by mapping the type of each value in the iterable with the provided function type `F`.
697
-
This is analogous to the JavaScript function `map`.
698
-
699
-
Following our example from [`$ObjMap<T>`](#toc-objmap), let's assume that `run` takes an array of functions, instead of an object, and maps over them returning an array of the function call results. We could annotate its return type like this:
700
-
701
-
```js
702
-
// Function type that takes a `() => V` and returns a `V` (its return type)
703
-
type ExtractReturnType =<V>(() =>V) =>V
704
-
705
-
function run<A, I: Array<() => A>>(iter: I): $TupleMap<I, ExtractReturnType> {
706
-
returniter.map(fn=>fn());
707
-
}
708
-
709
-
constarr= [() =>'foo', () =>'bar'];
710
-
run(arr)[0] as string; // Works
711
-
run(arr)[1] as string; // Works
712
-
run(arr)[1] as boolean; // Error!
713
-
```
632
+
Removed. Use [Mapped Types](../mapped-types) instead.
NOTE: Please use [Conditional Types](../conditional) or [Indexed Access Types](../indexed-access) to extract types instead.
718
-
719
-
`$Call<F, T...>` is a type that represents the result of calling the given [function type](../functions) `F` with 0 or more arguments `T...`.
720
-
This is analogous to calling a function at runtime (or more specifically, it's analogous to calling [`Function.prototype.call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call)), but at the type level; this means that function type calls happens statically, i.e. not at runtime.
721
-
722
-
Let's see a couple of examples:
723
-
```js
724
-
// Takes an object type, returns the type of its `prop` key
725
-
type ExtractPropType =<T>({prop:T, ...}) =>T;
726
-
type Obj = {prop: number};
727
-
type PropType = $Call<ExtractPropType, Obj>; // Call `ExtractPropType` with `Obj` as an argument
728
-
type Nope = $Call<ExtractPropType, {nope: number}>; // Error! Argument doesn't match `Obj`.
729
-
730
-
5 as PropType; // Works
731
-
true as PropType; // Error! PropType is a number
732
-
```
733
-
734
-
```js
735
-
// Takes a function type, and returns its return type
736
-
type ExtractReturnType =<R>(() =>R) =>R;
737
-
type Fn= () => number;
738
-
type ReturnType = $Call<ExtractReturnType, Fn>;
739
-
740
-
5 as ReturnType; // Works
741
-
true as ReturnType; // Error! ReturnType is a number
742
-
```
743
-
744
-
`$Call` can be very powerful because it allows you to make calls in type-land that you would otherwise have to do at runtime.
745
-
The type-land calls happen statically and will be erased at runtime.
746
-
747
-
```js
748
-
// Getting return types:
749
-
function getFirstValue<V>(map:Map<string, V>): ?V {
750
-
for (const [key, value] ofmap.entries()) {
751
-
return value;
752
-
}
753
-
returnnull;
754
-
}
755
-
756
-
// Using $Call, we can get the actual return type of the function above:
757
-
type Value = $Call<typeof getFirstValue, Map<string, number>>;
758
-
759
-
5 as Value;
760
-
true as Value; // Error! Value is a `number`
761
-
762
-
// We could generalize it further:
763
-
type GetMapValue<M>=
764
-
$Call<typeof getFirstValue, M>;
765
-
766
-
5 as GetMapValue<Map<string, number>>;
767
-
true as GetMapValue<Map<string, boolean>>;
768
-
true as GetMapValue<Map<string, number>>; // Error! value is a `number`
769
-
```
636
+
Removed. Use [Conditional Types](../conditional) or [Indexed Access Types](../indexed-access) instead.
NOTE: Please use [Mapped Types](../mapped-types) instead.
774
-
775
-
`ObjMap<T, F>` takes an [object type](../objects) `T`, and a [function type](../functions) `F`, and returns the object type obtained by mapping the type of each value in the object with the provided function type `F`. In other words, `$ObjMap` will [call](#toc-call) (at the type level) the given function type `F` for every property value type in `T`, and return the resulting object type from those calls.
776
-
777
-
Let's see an example. Suppose you have a function called `run` that takes an object of thunks (functions in the form `() =>A`) as input:
778
-
779
-
```js
780
-
function run<O: {[key: string]: (...ReadonlyArray<unknown>) => unknown}>(o:O): $FlowFixMe {
The function's purpose is to run all the thunks and return an object made of values. What's the return type of this function?
789
-
790
-
The keys are the same, but the values have a different type, namely the return type of each function.
791
-
At a value level (the implementation of the function) we're essentially mapping over the object to produce new values for the keys.
792
-
How to express this at a type level?
793
-
794
-
This is where `ObjMap<T, F>` comes in handy
795
-
796
-
```js
797
-
// let's write a function type that takes a `() => V` and returns a `V` (its return type)
798
-
type ExtractReturnType =<V>(() =>V) =>V;
799
-
800
-
declare function run<O: {[key: string]: (...ReadonlyArray<unknown>) => unknown}>(o:O): $ObjMap<O, ExtractReturnType>;
801
-
802
-
consto= {
803
-
a: () =>true,
804
-
b: () =>'foo'
805
-
};
806
-
807
-
run(o).a as boolean; // Works
808
-
run(o).b as string; // Works
809
-
run(o).b as boolean; // Error! `b` is a string
810
-
run(o).c; // Error! `c` was not in the original object
811
-
```
812
-
813
-
This is extremely useful for expressing the return type of functions that manipulate objects values.
814
-
You could use a similar approach (for instance) to provide the return type of bluebird's [`Promise.props`](http://bluebirdjs.com/docs/api/promise.props.html) function,
815
-
which is like `Promise.all` but takes an object as input.
816
-
817
-
Here's a possible declaration of this function, which is very similar to our first example:
0 commit comments