Utility Types
Flow provides a set of utility types to operate on other types to create new types.
keyof T ≥0.290 (alias $Keys<T>)
You can extract the type of the keys from an object type. Typically this will be a union of string literal types:
1const countries = {2 US: "United States",3 IT: "Italy",4 FR: "France"5};6
7type Country = keyof typeof countries;8
9const italy: Country = 'IT'; // Works10const nope: Country = 'nope'; // Error!prop-missingCannot assign 'nope' to nope because property nope is missing in object literal [1].In the example above, the type of Country is equivalent to type Country = 'US' | 'IT' | 'FR', but Flow was able to extract it from the keys of countries.
If you want to create an enum type, Flow Enums might be a better fit for your use-case.
Values<T> ≥0.290 (alias $Values<T>)
Values<T> represents the union type of all the value types of the enumerable properties in an object type,
or the elements of an array or tuple type (support for arrays and tuples in Flow version ≥0.240):
1type Props = {2 name: string,3 age: number,4};5
6// The following two types are equivalent:7type PropValues = string | number;8type Prop$Values = Values<Props>;9
10const name: Prop$Values = 'Jon'; // Works11const age: Prop$Values = 42; // Works12const fn: Prop$Values = true; // Error!incompatible-typeCannot assign true to fn because: Either boolean [1] is incompatible with number [2]. Or boolean [1] is incompatible with string [3].For arrays and tuples:
1type Arr = Array<string>;2type Str = Values<Arr>; //=> string3's' as Str; // OK4
5type Tup = [1, 2];6type Num = Values<Tup>; //=> 1 | 271 as Num; // OKNote that using Values on the typeof an object or array literal will result in a type more general than you might expect:
1const obj = {2 foo: 1,3 bar: 2,4};5
6function acceptsValues(x: Values<typeof obj>) { /* ... */ }7
8acceptsValues(1); // Works9acceptsValues(3); // Works, because the type was interpreted as `number`.This behavior changes if you use Object.freeze on the object literal expression:
1const obj = Object.freeze({2 foo: 1,3 bar: 2,4});5
6function acceptsValues(x: Values<typeof obj>) { /* ... */ }7
8acceptsValues(1); // Works9acceptsValues(3); // Error! Because the type was interpreted as `1 | 2`.incompatible-typeCannot call acceptsValues with 3 bound to x because number [1] is incompatible with Values [2].If you want to create an enum type, Flow Enums might be a better fit for your use-case.
Readonly<T> ≥0.290 (alias $ReadOnly<T>)
Readonly<T> is a type that represents the read-only version of a given object type
or tuple type T (support for tuples is for Flow ≥0.212).
A read-only object type is an object type whose keys are all read-only.
Similarly, a read-only tuple is one where each element is read-only.
This means that the following are equivalent:
1type ReadOnlyObj = {2 +key: number, // read-only field, marked by the `+` annotation3};4type ReadOnlyTuple = [+foo: number];→
1type ReadOnlyObj = Readonly<{2 key: number,3}>;4type ReadOnlyTuple = Readonly<[number]>;This is useful when you need to use a read-only version of an object type you've already defined, without manually having to re-define and annotate each key as read-only. For example:
1type Props = {2 name: string,3 age: number,4};5
6type ReadOnlyProps = Readonly<Props>;7
8function render(props: ReadOnlyProps) {9 const {name, age} = props; // Works10 props.age = 42; // Error!cannot-writeCannot assign 42 to props.age because property age is not writable.11}Additionally, other utility types, such as spread, may strip any read/write annotations, so Readonly<T> is a handy way to quickly make the object read-only again after operating on it:
1type Obj = {2 +key: number,3};4
5type MappedObj = Readonly<{...Obj, foo: string}> // Still read-onlyThe Readonly utility works on object and tuple types.
If you want to make other types read-only, you can use one of the following:
Array<T>->ReadonlyArray<T>Set<T>->ReadonlySet<T>Map<K, V>->ReadonlyMap<K, V>WeakSet<T>->ReadonlyWeakSet<T>WeakMap<K, V>->ReadonlyWeakMap<K, V>
Partial<T> ≥0.201
This utility converts all of an object or interface's named fields to be optional,
while maintaining all the object's other properties (e.g. exactness, variance).
Use this utility instead of $Shape.
Since Flow ≥0.212, it also converts all of a tuple type's elements to be optional.
Example for objects:
1type Person = {2 name: string,3 age: number,4};5type PartialPerson = Partial<Person>;6// Above equivalent to `{name?: string, age?: number}`7
8const a: PartialPerson = {}; // OK9const b: PartialPerson = {name: 'George'}; // OK10const c: PartialPerson = {name: 'George', age: 123}; // OK11
12c as Person; // ERROR: `PartialPerson` is not a `Person` (unlike with `$Shape`)incompatible-typeCannot cast c to Person because properties age and name of {age?: number, name?: string} [1] are not exactly the same as those of Person [2].For tuples:
1type AllRequired = [number, string];2[] as Partial<AllRequired>; // OK: like `[a?: number, b?: string]` nowA object or tuple of type T cannot be supplied to Partial<T>, due to mutability. You can resolve this by making the object read-only:
1type Person = {2 name: string,3 age: number,4};5
6const person: Person = {name: 'George', age: 123};7
8function noPerson(o: Partial<Person>) {9 // Can mutate:10 o.name = undefined;11}12noPerson(person); // Error!incompatible-typeCannot call noPerson with person bound to o because properties age and name of Person [1] are not exactly the same as those of {age?: number, name?: string} [2].13
14function okPerson(o: Readonly<Partial<Person>>) {15 // Can't mutate - it's read-only!16}17okPerson(person); // WorksNote: Up until Flow version 0.201, this utility type was named $Partial.
Required<T> ≥0.201
The Required utility type is the opposite of Partial:
it converts all of an object or interface’s optional fields to be required.
Since Flow ≥0.212, it also converts all of a tuple type's elements to be required.
Example for objects:
1type PartialPerson = {2 name?: string,3 age?: number,4};5type Person = Required<PartialPerson>;6// Above equivalent to `{name: string, age: number}`7
8const a: Person = {name: 'George', age: 123}; // OK9const b: Person = {age: 123}; // ERROR: missing `name` propertyincompatible-typeCannot assign object literal to b because property name is missing in object literal [1] but exists in PartialPerson [2].For tuples:
1type AllOptional = [a?: number, b?: string];2[] as Required<AllOptional>; // ERROR: like `[a: number, b: string]` nowinvalid-tuple-arityCannot cast array literal to required of AllOptional because empty array literal [1] has 0 elements but AllOptional [2] has 2 elements.ReturnType<F> ≥0.209
This utility type extracts the return type from a given function type.
1declare function f(s: string, n: number): boolean;2type Bool = ReturnType<typeof f>;3true as Bool;41 as Bool; // Error: number is not booleanincompatible-typeCannot cast 1 to Bool because number [1] is incompatible with boolean [2].Parameters<F> ≥0.209
This utility type extracts the parameter types from a given function type into a tuple type.
1declare function f(s: string, n: number): boolean;2type Tuple = Parameters<typeof f>; // Evaluates to [string, number]3's' as Tuple[0];41 as Tuple[1];5false as Tuple[2]; // Error: tuple type only has two elementsinvalid-tuple-indexCannot access number literal 2 on Tuple because tuple type [1] only has 2 elements, so index 2 is out of bounds.Exclude<T, U> ≥0.209
This utility type excludes all subtypes of U from T.
1type T = Exclude<1 | 2 | 3 | 4, 1 | 3>; // evaluates to 2 | 421 as T; // errorincompatible-typeCannot cast 1 to T because number [1] is incompatible with Exclude [2].32 as T; // ok43 as T; // errorincompatible-typeCannot cast 3 to T because number [1] is incompatible with Exclude [2].54 as T; // okExtract<T, U> ≥0.209
This utility type retains only subtypes of U from T.
1declare class Car {}2declare class Animal {}3declare class Dog extends Animal {}4declare class Cat extends Animal {}5type T = Extract<Car | Dog | Cat, Animal>; // evaluates to Dog | Cat6new Car() as T; // errorincompatible-typeCannot cast new Car() to T because: Either Car [1] is incompatible with Dog [2]. Or Car [1] is incompatible with Cat [3].7new Dog() as T; // ok8new Cat() as T; // okThisParameterType<F> ≥0.209
This utility type extracts the type of the this parameter of a given function type.
1type T = ThisParameterType<(this: number, bar: string) => void>; // Evaluates to number2'1' as T; // errorincompatible-typeCannot cast '1' to T because string [1] is incompatible with number [2].32 as T; // okOmitThisParameter<F> ≥0.209
This utility type removes the this parameter from a given function type.
1type HasThisParamFun = (this: number, bar: string) => void;2type NoThisParamFun = OmitThisParameter<HasThisParamFun> // Evaluates to (bar: string) => void3declare const hasThisParam: HasThisParamFun;4declare const noThisParam: NoThisParamFun;5
6hasThisParam(''); // error: global object is not numberincompatible-typeCannot call hasThisParam because global object [1] is incompatible with number [2].7noThisParam(''); // ok: no this type requirementAwaited<T> ≥0.246
Awaited<T> unwraps a Promise type to extract the type of its resolved value. If T is not a Promise, it returns T unchanged.
1type Response = Awaited<Promise<string>>; // Evaluates to string2'hello' as Response; // OK342 as Response; // Error: number is not stringincompatible-typeCannot cast 42 to Response because number [1] is incompatible with string [2].This is useful when you need to refer to the resolved type of a Promise without manually unwrapping it. If T is not a Promise, Awaited<T> simply evaluates to T:
1type A = Awaited<Promise<number>>; // number2type B = Awaited<string>; // string (non-Promise types are returned as-is)3
442 as A; // OK5'hello' as B; // OK6'hello' as A; // Error: string is not numberincompatible-typeCannot cast 'hello' to A because string [1] is incompatible with number [2].742 as B; // Error: number is not stringincompatible-typeCannot cast 42 to B because number [1] is incompatible with string [2].You can combine Awaited with other utility types like ReturnType to extract the resolved type from an async function's return type:
1async function fetchUser(): Promise<{name: string}> {2 return {name: 'George'};3}4
5type User = Awaited<ReturnType<typeof fetchUser>>;6
7const user: User = {name: 'George'}; // OK8const bad: User = 'not a user'; // Errorincompatible-typeCannot assign 'not a user' to bad because string [1] is incompatible with object type [2].