Utility Types
Flow provides a set of utility types to operate on other types to create new types.
keyof 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>
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:
1type Props = {2 name: string,3 age: number,4};5
6// The following two types are equivalent:7type PropValues = string | number;8type PropValues2 = Values<Props>;9
10const name: PropValues2 = 'Jon'; // Works11const age: PropValues2 = 42; // Works12const fn: PropValues2 = 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>
Readonly<T> is a type that represents the read-only version of a given object type
or tuple type T.
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>
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).
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`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); // WorksRequired<T>
The Required utility type is the opposite of Partial:
it converts all of an object or interface’s optional fields to be required.
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>
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>
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>
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>
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>
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>
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>
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>
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; // okOmit<O, Keys>
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>
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 errorNonNullable<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>
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 T — NoInfer 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 | numberBecause 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); // OKHere 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> maps each property of an object
to the type of the property key. For example:
1const obj = {2 a: true,3 b: 'foo'4};5
6declare function run<O extends {...}>(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].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
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.
$Exact<T> (Discouraged)
Avoid $Exact<T>. Start with an exact object type and derive inexact variants from it using object type spread.
$Exact makes 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;Prefer the inverse: define the exact type and spread it into the inexact one.
1type ExactUser = {name: string};2type InexactUser = {...ExactUser, ...};3
4const user = {name: 'John Wilkes Booth'};5const a: ExactUser = user;See Also
- Mapped Types — a general mechanism for transforming object types (generalizes many utility types)
- Conditional Types — type-level conditionals for more complex transformations
- Generics — most utility types are generic; understanding generics helps use them effectively
- Indexed Access Types — extracting property types from objects and tuples