Skip to main content

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; // OK

Note 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-only

The 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]` now

A 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); // Works

Note: 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; // ok

Extract<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; // ok

ThisParameterType<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; // ok

OmitThisParameter<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 requirement

Awaited<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].

Pick<O, Keys> 0.211

This utility type allows you to generate an object type using a subset of the fields from another object type.

1type O = {foo: number, bar: string, baz: boolean};2type FooAndBar = Pick<O, 'foo' | 'bar'>;3
4declare const fooAndBar: FooAndBar;5fooAndBar.baz; // error: baz is missingprop-missingCannot get fooAndBar.baz because property baz (did you mean bar?) is missing in Pick [1].6fooAndBar.foo as number; // ok7fooAndBar.bar as string; // ok

Omit<O, Keys> 0.211

This utility type allows you to generate an object type by omitting the specified fields from another object type.

1type O = {foo: number, bar: string, baz: boolean};2type JustBaz= Omit<O, 'foo' | 'bar'>;3
4declare const justBaz: JustBaz;5justBaz.baz as boolean; // ok6justBaz.foo; // error: missing fooprop-missingCannot get justBaz.foo because property foo is missing in Omit [1].7justBaz.bar; // error: missing barprop-missingCannot get justBaz.bar because property bar (did you mean baz?) is missing in Omit [1].

Record<Keys, Type> 0.211

This utility type allows you to generate an object type from a union of keys with the given Type for each field.

1type NumberRecord = Record<'foo' | 'bar', number>;2declare const numberRecord: NumberRecord;3numberRecord.foo as number; // ok4numberRecord.bar as number; // ok5numberRecord.baz; // errorprop-missingCannot get numberRecord.baz because property baz (did you mean bar?) is missing in Record [1].

Note that Record is different than using an indexer:

1type NumberRecord = Record<'foo' | 'bar', number>;2type IndexedObject = {['foo' | 'bar']: number};3
4// Record uses explicit fields, which means they are all required5const rec: NumberRecord = {}; // errorincompatible-typeCannot assign object literal to rec because properties bar and foo are missing in object literal [1] but exist in Record [2].6// Indexers do not have this same requirement7const idx: IndexedObject = {}; // no error

$Exact<T>

You can use $Exact to make an inexact object type exact:

1type InexactUser = {name: string, ...};2type ExactUser = $Exact<InexactUser>;3
4const user = {name: 'John Wilkes Booth'};5// These will both be satisfied because they are equivalent:6const a: ExactUser = user;7const b: {name: string} = user;

This is a utility type to avoid, as it's clearer and more concise to start off with an exact object type and make it inexact using object type spread (if you wish to have both inexact and exact variants of one object type):

1type ExactUser = {name: string};2type InexactUser = {...ExactUser, ...};3
4const user = {name: 'John Wilkes Booth'};5const a: ExactUser = user;

NonNullable<T> 0.290 (alias $NonMaybeType<T>)

NonNullable<T> converts a type T to a non-maybe type. In other words, the values of NonNullable<T> are the values of T except for null and undefined.

1type MaybeName = ?string;2type Name = NonNullable<MaybeName>;3
4'Gabriel' as MaybeName; // Works5null as MaybeName; // Works6'Gabriel' as Name; // Works7null as Name; // Error! `null` can't be annotated as Name because Name is not a maybe typeincompatible-typeCannot cast null to Name because null [1] is incompatible with string [2].

NoInfer<T> 0.230

NoInfer<T> prevents a type parameter from being inferred from the wrapped position. When Flow infers a type parameter T, it normally considers every position where T appears. Wrapping a position in NoInfer excludes it from inference, so T is determined only by the remaining (unwrapped) positions. The resulting type is still TNoInfer only affects inference, not the type itself.

This is useful when a generic function has multiple parameters that share a type parameter, but you want only some of them to drive inference. Without NoInfer, Flow may widen the type parameter to accommodate all arguments, allowing mismatches to go undetected.

Consider a function where both parameters use the same type parameter T:

1declare function assertEqual<T>(actual: T, expected: T): void;2
3assertEqual('hello', 42); // No error: T is inferred as string | number

Because both arguments contribute to inference, Flow widens T to string | number, and the call succeeds even though the two arguments have different types.

By wrapping the expected parameter with NoInfer, you can ensure T is inferred only from actual:

1declare function assertEqual<T>(actual: T, expected: NoInfer<T>): void;2
3assertEqual('hello', 'world'); // OK4assertEqual('hello', 42); // Error!incompatible-typeCannot call assertEqual with 42 bound to expected because number [1] is incompatible with string [2].

Now T is inferred as string from the first argument alone, and 42 fails to match.

Nested types

NoInfer also works when T appears inside a more complex type. Any occurrence of the type parameter within NoInfer is excluded from inference:

1declare function createSignal<T>(2  initialValue: T,3  defaultValue: NoInfer<T>,4): void;5
6createSignal('hello', 'default'); // OK7createSignal('hello', 42); // Error!incompatible-typeCannot call createSignal with 42 bound to defaultValue because number [1] is incompatible with string [2].

Callbacks

You can use NoInfer in callback parameter positions to prevent the callback from influencing the type parameter while still receiving the inferred type:

1declare function filter<T>(2  items: Array<T>,3  predicate: (item: NoInfer<T>) => boolean,4): Array<T>;5
6const numbers: Array<number> = [1, 2, 3];7filter(numbers, (item) => item > 1); // OK

Here T is inferred as number from the items argument. The predicate callback receives item typed as number but does not participate in inferring T.

$KeyMirror<O>

$KeyMirror<Obj> is a special case of $ObjMapi<Obj, F>, when F is the identity function type, ie. <K>(K) => K. In other words, it maps each property of an object to the type of the property key. Instead of writing $ObjMapi<Obj, <K>(K) => K>, you can write $KeyMirror<Obj>. For example:

1const obj = {2  a: true,3  b: 'foo'4};5
6declare function run<O: {...}>(o: O): $KeyMirror<O>;7
8// newObj is of type {a: 'a', b: 'b'}9const newObj = run(obj);10
11newObj.a as 'a'; // Works12newObj.b as 'a'; // Error! String 'b' is incompatible with 'a'incompatible-typeCannot cast newObj.b to string literal a because string literal b [1] is incompatible with string literal a [2].

Tip: Prefer using $KeyMirror instead of $ObjMapi (if possible) to fix certain kinds of [invalid-exported-annotation] errors.

Class<T>

Given a type T representing instances of a class C, the type Class<T> is the type of the class C. For example:

1class Store {}2class ExtendedStore extends Store {}3class Model {}4
5function makeStore(storeClass: Class<Store>) {6  return new storeClass();7}8
9makeStore(Store) as Store;10makeStore(ExtendedStore) as Store;11makeStore(Model) as Model; // Error!incompatible-typeCannot cast makeStore(...) to Model because Store [1] is incompatible with Model [2].incompatible-typeCannot call makeStore with Model bound to storeClass because Model [1] is incompatible with Store [2].

For classes that take type parameters, you must also provide the parameter. For example:

1class ParamStore<T> {2  constructor(data: T) {}3}4
5function makeParamStore<T>(storeClass: Class<ParamStore<T>>, data: T): ParamStore<T> {6  return new storeClass(data);7}8makeParamStore(ParamStore, 1) as ParamStore<number>;9makeParamStore(ParamStore, 1) as ParamStore<boolean>; // Error!incompatible-typeCannot call makeParamStore with 1 bound to data because number [1] is incompatible with boolean [2].

$Exports<T>

The following are functionally equivalent

import typeof * as T from 'my-module';
type T = $Exports<'my-module'>;

The advantage of the $Exports syntax is that you can export the type on the same line

export type T = $Exports<'my-module'>;

where as you would otherwise need to export an alias in the import typeof case

import typeof * as T from 'my-module';
export type MyModuleType = T;

StringPrefix and StringSuffix 0.242

The StringPrefix and StringSuffix types represent strings with the specified prefix or suffix, respectively. Their first type argument must be a string literal type, representing the prefix or suffix.

You could use StringPrefix to define a type that accepts strings which start with data-:

1type DataProp = StringPrefix<'data-'>;2'data-foo' as DataProp; // OK3'data-bar' as DataProp; // OK4'random string' as DataProp; // ERRORincompatible-typeCannot cast 'random string' to DataProp because string [1] is incompatible with string prefixed with data- [2].

You could use StringSuffix to define a type that accepts strings which end with !:

1type Exclaim = StringSuffix<'!'>;2'yay!' as Exclaim; // OK3'woo!' as Exclaim; // OK4'random string' as Exclaim; // ERRORincompatible-typeCannot cast 'random string' to Exclaim because string [1] is incompatible with string suffixed with ! [2].

You can combine these with intersection types:

1type CSSVar = StringPrefix<'var(--'> & StringSuffix<')'>;2'var(--color)' as CSSVar; // OK3'random string' as CSSVar; // ERRORincompatible-typeCannot cast 'random string' to CSSVar because string [1] is incompatible with string prefixed with var(-- [2].incompatible-typeCannot cast 'random string' to CSSVar because string [1] is incompatible with string suffixed with ) [2].

Both utilities accept an optional second type argument, which is the type of the remainder:

1type Price = StringPrefix<'$', '1' | '2'>;2'$1' as Price; // OK3'$2' as Price; // OK4'$999' as Price; // ERRORincompatible-typeCannot cast '$999' to Price because string with prefix $ removed [1] is incompatible with union type [2].

When not specified, the type of the remainder is just string.

Removed utility types

These utility types have been removed. Use the recommended replacements instead.

$Diff<A, B> 0.267

Removed. Use Omit instead.

$Rest<A, B> 0.266

Removed. Use Omit instead.

$PropertyType<T, k> 0.265

Removed. Use the T['k'] indexed access type instead.

$ElementType<T, K> 0.265

Removed. Use the T[K] indexed access type instead.

$TupleMap<T, F> 0.247

Removed. Use Mapped Types instead.

$Call<F, T...> 0.247

Removed. Use Conditional Types or Indexed Access Types instead.

$ObjMap<T, F> 0.246

Removed. Use Mapped Types instead.

$ObjMapi<T, F> 0.246

Removed. Use Mapped Types instead.

$ObjMapConst<O, T> 0.246

Removed. Use Mapped Types instead.

$Partial 0.202

Removed. Use Partial instead.

$Shape<T> 0.206

Removed. Use Partial instead.