Skip to content

Commit 6cbf5e3

Browse files
gkzmeta-codesync[bot]
authored andcommitted
[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
1 parent f575751 commit 6cbf5e3

File tree

1 file changed

+13
-283
lines changed

1 file changed

+13
-283
lines changed

website/docs/types/utilities.md

Lines changed: 13 additions & 283 deletions
Original file line numberDiff line numberDiff line change
@@ -609,318 +609,48 @@ When not specified, the type of the remainder is just `string`.
609609
610610
## Removed utility types
611611
612-
These utility types used to exist, but no longer exist in latest versions of Flow.
612+
These utility types have been removed. Use the recommended replacements instead.
613613
614614
### `$Diff<A, B>` <UntilVersion version="0.267" /> {#toc-diff}
615615
616-
NOTE: Please use `Omit` type instead.
617-
618-
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-
function setProps(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-
function setProps(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:
651-
652-
```js
653-
type A = $Diff<{}, {nope: number}>; // Error!
654-
type B = $Diff<{}, {nope: number | void}>; // Works
655-
656-
const a: A = {};
657-
const b: B = {};
658-
```
616+
Removed. Use [`Omit`](#toc-omit) instead.
659617
660618
### `$Rest<A, B>` <UntilVersion version="0.266" /> {#toc-rest}
661619
662-
NOTE: Please use `Omit` type instead.
663-
664-
`$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}`.
620+
Removed. Use [`Omit`](#toc-omit) instead.
684621
685622
### `$PropertyType<T, k>` <UntilVersion version="0.265" /> {#toc-propertytype}
686623
687-
`$PropertyType<T, 'k'>` is equivalent to the `T['k']` [indexed access type](../indexed-access).
624+
Removed. Use the `T['k']` [indexed access type](../indexed-access) instead.
688625
689626
### `$ElementType<T, K>` <UntilVersion version="0.265" /> {#toc-elementtype}
690627
691-
`$ElementType<T, K>` is equivalent to the `T[K]` [indexed access type](../indexed-access).
628+
Removed. Use the `T[K]` [indexed access type](../indexed-access) instead.
692629
693630
### `$TupleMap<T, F>` <UntilVersion version="0.247" /> {#toc-tuplemap}
694631
695-
`$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-
return iter.map(fn => fn());
707-
}
708-
709-
const arr = [() => '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.
714633
715634
### `$Call<F, T...>` <UntilVersion version="0.247" /> {#toc-call}
716635
717-
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] of map.entries()) {
751-
return value;
752-
}
753-
return null;
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.
770637
771638
### `$ObjMap<T, F>` <UntilVersion version="0.246" /> {#toc-objmap}
772639
773-
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 {
781-
return Object.keys(o).reduce<{[string]: (...ReadonlyArray<unknown>) => unknown}>(
782-
(acc, k) => ({...acc, [(k: string)]: o[k]()}),
783-
{},
784-
);
785-
}
786-
```
787-
788-
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-
const o = {
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:
818-
819-
```js
820-
declare function props<A, O: {[key: string]: A}>(promises: O): Promise<$ObjMap<O, <T>(p: Promise<T> | T) => T>>>;
821-
822-
const promises = {a: Promise.resolve(42)};
823-
props(promises).then(o => {
824-
o.a as 42; // Works
825-
o.a as 43; // Error! Flow knows it's 42
826-
});
827-
```
640+
Removed. Use [Mapped Types](../mapped-types) instead.
828641
829642
### `$ObjMapi<T, F>` <UntilVersion version="0.246" /> {#toc-objmapi}
830643
831-
NOTE: Please use [Mapped Types](../mapped-types) instead.
832-
833-
`ObjMapi<T, F>` is similar to [`ObjMap<T, F>`](#toc-objmap). The difference is that function
834-
type `F` will be [called](#toc-call) with both the key and value types of the elements of
835-
the object type `T`, instead of just the value types. For example:
836-
837-
```js
838-
const o = {
839-
a: () => true,
840-
b: () => 'foo'
841-
};
842-
843-
type ExtractReturnObjectType = <K, V>(K, () => V) => { k: K, v: V };
844-
845-
declare function run<O: {...}>(o: O): $ObjMapi<O, ExtractReturnObjectType>;
846-
847-
run(o).a as {k: 'a', v: boolean}; // Works
848-
run(o).b as {k: 'b', v: string}; // Works
849-
run(o).a as {k: 'b', v: boolean}; // Error! `a.k` is "a"
850-
run(o).b as {k: 'b', v: number}; // Error! `b.v` is a string
851-
run(o).c; // Error! `c` was not in the original object
852-
```
644+
Removed. Use [Mapped Types](../mapped-types) instead.
853645
854646
### `$ObjMapConst<O, T>` <UntilVersion version="0.246" /> {#toc-objmapconst}
855647
856-
NOTE: Please use [Mapped Types](../mapped-types) instead.
857-
858-
`$ObjMapConst<Obj, T>` is a special case of `$ObjMap<Obj, F>`, when `F` is a constant
859-
function type, e.g. `() => T`. Instead of writing `$ObjMap<Obj, () => T>`, you
860-
can write `$ObjMapConst<Obj, T>`. For example:
861-
```js
862-
const obj = {
863-
a: true,
864-
b: 'foo'
865-
};
866-
867-
declare function run<O: {...}>(o: O): $ObjMapConst<O, number>;
868-
869-
// newObj is of type {a: number, b: number}
870-
const newObj = run(obj);
871-
872-
newObj.a as number; // Works
873-
newObj.b as string; // Error! Property `b` is a number
874-
```
875-
876-
Tip: Prefer using `$ObjMapConst` instead of `$ObjMap` (if possible) to fix certain
877-
kinds of `[invalid-exported-annotation]` errors.
648+
Removed. Use [Mapped Types](../mapped-types) instead.
878649
879650
### `$Partial` <UntilVersion version="0.202" />
880-
A former alias of [Partial](#toc-partial). Support was removed in version 0.203.
881-
882-
### `$Shape<T>` <UntilVersion version="0.206" /> {#toc-shape}
883-
884-
NOTE: This utility is unsafe - please use [`Partial`](#toc-partial) documented above to make all of an object's fields optional.
885651
886-
A variable of type `$Shape<T>`, where `T` is some object type, can be assigned objects `o`
887-
that contain a subset of the properties included in `T`. For each property `p: S` of `T`,
888-
the type of a potential binding of `p` in `o` must be compatible with `S`.
652+
Removed. Use [`Partial`](#toc-partial) instead.
889653
890-
For example
891-
```js
892-
type Person = {
893-
age: number,
894-
name: string,
895-
};
896-
// $FlowIgnore[deprecated-utility]
897-
type PersonDetails = $Shape<Person>;
898-
899-
const person1: Person = {age: 28}; // ERROR: missing `name`
900-
const person2: Person = {name: 'a'}; // ERROR: missing `age`
901-
const person3: PersonDetails = {age: 28}; // OK
902-
const person4: PersonDetails = {name: 'a'}; // OK
903-
const person5: PersonDetails = {age: 28, name: 'a'}; // OK
904-
const person6: PersonDetails = {age: '28'}; // ERROR: string is incompatible with number
905-
```
906-
907-
NOTE: `$Shape<T>` is **not** equivalent to `T` with all its fields marked as optional.
908-
In particular, Flow unsoundly allows `$Shape<T>` to be used as a `T` in several
909-
contexts. For example in
910-
911-
```js
912-
const personShape: PersonDetails = {age: 28};
913-
personShape as Person;
914-
```
915-
Flow will unsoundly allow this last cast to succeed.
916-
917-
It is also not equivalent to itself in some contexts:
918-
919-
```js
920-
function f<T>(input: $Shape<T>): $Shape<T> {
921-
return input; // ERROR: `T` is incompatible with `$Shape` of `T`
922-
}
923-
```
654+
### `$Shape<T>` <UntilVersion version="0.206" /> {#toc-shape}
924655
925-
This utility type is deprecated and will be deleted in the future -
926-
use [`Partial`](#toc-partial) instead.
656+
Removed. Use [`Partial`](#toc-partial) instead.

0 commit comments

Comments
 (0)