Utility Types
Flow provides a set of utility types to operate on other types to create new types.
Most utility types align directly with TypeScript: Readonly, Pick, Omit, Record, Partial, Required, Exclude, Extract, NonNullable, Parameters, ReturnType, ConstructorParameters, InstanceType, Awaited, ThisParameterType, OmitThisParameter, NoInfer, Uppercase, Lowercase, Capitalize, Uncapitalize, and keyof. See Concepts that transfer cleanly from TypeScript for more.
keyof T
You can extract the type of the keys from an object type. Typically this will be a union of string literal types:
const countries = {
US: "United States",
IT: "Italy",
FR: "France"
};
type Country = keyof typeof countries;
const italy: Country = 'IT'; // Works
const nope: Country = 'nope'; // Error! 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 properties in an object type, or the elements of an array or tuple type:
type Props = {
name: string,
age: number,
};
// The following two types are equivalent:
type PropValues = string | number;
type PropValues2 = Values<Props>;
const name: PropValues2 = 'Jon'; // Works
const age: PropValues2 = 42; // Works
const fn: PropValues2 = true; // Error! For arrays and tuples:
type Arr = Array<string>; type Str = Values<Arr>; //=> string 's' as Str; // OK type Tup = [1, 2]; type Num = Values<Tup>; //=> 1 | 2 1 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:
const obj = {
foo: 1,
bar: 2,
};
function acceptsValues(x: Values<typeof obj>) { /* ... */ }
acceptsValues(1); // Works
acceptsValues(3); // Works, because the type was interpreted as `number`. This behavior changes if you use Object.freeze on the object literal expression:
const obj = Object.freeze({
foo: 1,
bar: 2,
});
function acceptsValues(x: Values<typeof obj>) { /* ... */ }
acceptsValues(1); // Works
acceptsValues(3); // Error! Because the type was interpreted as `1 | 2`. If you want to create an enum type, Flow Enums might be a better fit for your use-case.
TypeScript has no Values<T> utility; the equivalent is the indexed access T[keyof T].
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:
type ReadOnlyObj = {
readonly key: number, // read-only field, marked by the `readonly` keyword
};
type ReadOnlyTuple = [readonly foo: number]; →
type ReadOnlyObj = Readonly<{
key: number,
}>;
type 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:
type Props = {
name: string,
age: number,
};
type ReadOnlyProps = Readonly<Props>;
function render(props: ReadOnlyProps) {
const {name, age} = props; // Works
props.age = 42; // Error!
} 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:
type Obj = {
readonly key: number,
};
type 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>
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:
type Person = {
name: string,
age: number,
};
type PartialPerson = Partial<Person>;
// Above equivalent to `{name?: string, age?: number}`
const a: PartialPerson = {}; // OK
const b: PartialPerson = {name: 'George'}; // OK
const c: PartialPerson = {name: 'George', age: 123}; // OK
c as Person; // ERROR: `PartialPerson` is not a `Person` For tuples:
type AllRequired = [number, string]; [] as Partial<AllRequired>; // OK: like `[a?: number, b?: string]` now
An 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:
type Person = {
name: string,
age: number,
};
const person: Person = {name: 'George', age: 123};
function noPerson(o: Partial<Person>) {
// Can mutate:
o.name = undefined;
}
noPerson(person); // Error!
function okPerson(o: Readonly<Partial<Person>>) {
// Can't mutate - it's read-only!
}
okPerson(person); // Works
Required<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:
type PartialPerson = {
name?: string,
age?: number,
};
type Person = Required<PartialPerson>;
// Above equivalent to `{name: string, age: number}`
const a: Person = {name: 'George', age: 123}; // OK
const b: Person = {age: 123}; // ERROR: missing `name` property For tuples:
type AllOptional = [a?: number, b?: string]; [] as Required<AllOptional>; // ERROR: like `[a: number, b: string]` now
Pick<O, Keys>
This utility type allows you to generate an object type using a subset of the fields from another object type.
type O = {foo: number, bar: string, baz: boolean};
type FooAndBar = Pick<O, 'foo' | 'bar'>;
declare const fooAndBar: FooAndBar;
fooAndBar.baz; // error: baz is missing
fooAndBar.foo as number; // ok
fooAndBar.bar as string; // ok
Omit<O, Keys>
This utility type allows you to generate an object type by omitting the specified fields from another object type.
type O = {foo: number, bar: string, baz: boolean};
type JustBaz= Omit<O, 'foo' | 'bar'>;
declare const justBaz: JustBaz;
justBaz.baz as boolean; // ok
justBaz.foo; // error: missing foo
justBaz.bar; // error: missing bar
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.
type NumberRecord = Record<'foo' | 'bar', number>; declare const numberRecord: NumberRecord; numberRecord.foo as number; // ok numberRecord.bar as number; // ok numberRecord.baz; // error
Note that Record is different than using an indexer:
type NumberRecord = Record<'foo' | 'bar', number>;
type IndexedObject = {['foo' | 'bar']: number};
// Record uses explicit fields, which means they are all required
const rec: NumberRecord = {}; // error
// Indexers do not have this same requirement
const idx: IndexedObject = {}; // no error
Exclude<T, U>
This utility type excludes all subtypes of U from T.
type T = Exclude<1 | 2 | 3 | 4, 1 | 3>; // evaluates to 2 | 4 1 as T; // error 2 as T; // ok 3 as T; // error 4 as T; // ok
Extract<T, U>
This utility type retains only subtypes of U from T.
declare class Car {}
declare class Animal {}
declare class Dog extends Animal {}
declare class Cat extends Animal {}
type T = Extract<Car | Dog | Cat, Animal>; // evaluates to Dog | Cat
new Car() as T; // error
new Dog() as T; // ok
new Cat() as T; // ok
ReturnType<F>
This utility type extracts the return type from a given function type.
declare function f(s: string, n: number): boolean; type Bool = ReturnType<typeof f>; true as Bool; 1 as Bool; // Error: number is not boolean
Parameters<F>
This utility type extracts the parameter types from a given function type into a tuple type.
declare function f(s: string, n: number): boolean; type Tuple = Parameters<typeof f>; // Evaluates to [string, number] 's' as Tuple[0]; 1 as Tuple[1]; false as Tuple[2]; // Error: tuple type only has two elements
ConstructorParameters<C> ≥0.317
This utility type extracts the parameter types of a class's constructor into a tuple type. Pass the class itself via typeof:
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
type PointArgs = ConstructorParameters<typeof Point>; // Evaluates to [number, number]
[1, 2] as PointArgs; // OK
'x' as PointArgs[0]; // Error: string is not number A class with no explicit constructor uses its synthesized default constructor, which takes no arguments:
class Empty {}
type EmptyArgs = ConstructorParameters<typeof Empty>; // Evaluates to []
[] as EmptyArgs; // OK
[1] as EmptyArgs; // Error: default constructor takes no arguments A class without its own constructor inherits the parameters of its parent's constructor:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {} // no explicit constructor
type DogArgs = ConstructorParameters<typeof Dog>; // Inherited [string]
['Rex'] as DogArgs; // OK
[1] as DogArgs; // Error: number is not string
InstanceType<C> ≥0.317
This utility type extracts the instance type produced by a class's constructor. Pass the class itself via typeof:
class User {
name: string;
constructor(name: string) {
this.name = name;
}
}
type UserInstance = InstanceType<typeof User>; // Evaluates to User
declare const u: UserInstance;
u.name as string; // OK
u as User; // OK This is useful when you have the type of a class (the static side, e.g. from a generic bound or a Class<T>) and need the type of the values it constructs.
For a generic class with no inference context, the class's type parameters resolve to their bounds (defaulting to unknown):
class Box<T> {
value: T;
constructor(value: T) {
this.value = value;
}
}
type BoxInstance = InstanceType<typeof Box>; // Box<unknown>
declare const b: BoxInstance;
b.value as unknown; // OK
ThisParameterType<F>
This utility type extracts the type of the this parameter of a given function type.
type T = ThisParameterType<(this: number, bar: string) => void>; // Evaluates to number '1' as T; // error 2 as T; // ok
OmitThisParameter<F>
This utility type removes the this parameter from a given function type.
type HasThisParamFun = (this: number, bar: string) => void;
type NoThisParamFun = OmitThisParameter<HasThisParamFun> // Evaluates to (bar: string) => void
declare const hasThisParam: HasThisParamFun;
declare const noThisParam: NoThisParamFun;
hasThisParam(''); // error: global object is not number
noThisParam(''); // ok: no this type requirement
Awaited<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.
type Response = Awaited<Promise<string>>; // Evaluates to string 'hello' as Response; // OK 42 as Response; // Error: number is not string
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:
type A = Awaited<Promise<number>>; // number type B = Awaited<string>; // string (non-Promise types are returned as-is) 42 as A; // OK 'hello' as B; // OK 'hello' as A; // Error: string is not number 42 as B; // Error: number is not string
You can combine Awaited with other utility types like ReturnType to extract the resolved type from an async function's return type:
async function fetchUser(): Promise<{name: string}> {
return {name: 'George'};
}
type User = Awaited<ReturnType<typeof fetchUser>>;
const user: User = {name: 'George'}; // OK
const bad: User = 'not a user'; // Error
NonNullable<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.
type MaybeName = ?string; type Name = NonNullable<MaybeName>; 'Gabriel' as MaybeName; // Works null as MaybeName; // Works 'Gabriel' as Name; // Works null as Name; // Error! `null` can't be annotated as Name because Name is not a maybe type
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:
declare function assertEqual<T>(actual: T, expected: T): void;
assertEqual('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:
declare function assertEqual<T>(actual: T, expected: NoInfer<T>): void;
assertEqual('hello', 'world'); // OK
assertEqual('hello', 42); // Error! 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:
declare function createSignal<T>(
initialValue: T,
defaultValue: NoInfer<T>,
): void;
createSignal('hello', 'default'); // OK
createSignal('hello', 42); // Error! Callbacks
You can use NoInfer in callback parameter positions to prevent the callback from influencing the type parameter while still receiving the inferred type:
declare function filter<T>( items: Array<T>, predicate: (item: NoInfer<T>) => boolean, ): Array<T>; const numbers: Array<number> = [1, 2, 3]; filter(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> maps each property of an object to the type of the property key. For example:
const obj = {
a: true,
b: 'foo'
};
declare function run<O extends {...}>(o: O): $KeyMirror<O>;
// newObj is of type {a: 'a', b: 'b'}
const newObj = run(obj);
newObj.a as 'a'; // Works
newObj.b as 'a'; // Error! String 'b' is incompatible with 'a'
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:
class Store {}
class ExtendedStore extends Store {}
class Model {}
function makeStore(storeClass: Class<Store>) {
return new storeClass();
}
makeStore(Store) as Store;
makeStore(ExtendedStore) as Store;
makeStore(Model) as Model; // Error! For classes that take type parameters, you must also provide the parameter. For example:
class ParamStore<T> {
constructor(data: T) {}
}
function makeParamStore<T>(storeClass: Class<ParamStore<T>>, data: T): ParamStore<T> {
return new storeClass(data);
}
makeParamStore(ParamStore, 1) as ParamStore<number>;
makeParamStore(ParamStore, 1) as ParamStore<boolean>; // Error! TypeScript has no native equivalent of Class<T>; the usual encodings are new (...args: any[]) => T, or typeof C for a specific class.
$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-:
type DataProp = StringPrefix<'data-'>; 'data-foo' as DataProp; // OK 'data-bar' as DataProp; // OK 'random string' as DataProp; // ERROR
You could use StringSuffix to define a type that accepts strings which end with !:
type Exclaim = StringSuffix<'!'>; 'yay!' as Exclaim; // OK 'woo!' as Exclaim; // OK 'random string' as Exclaim; // ERROR
You can combine these with intersection types:
type CSSVar = StringPrefix<'var(--'> & StringSuffix<')'>; 'var(--color)' as CSSVar; // OK 'random string' as CSSVar; // ERROR
Both utilities accept an optional second type argument, which is the type of the remainder:
type Price = StringPrefix<'$', '1' | '2'>; '$1' as Price; // OK '$2' as Price; // OK '$999' as Price; // ERROR
When not specified, the type of the remainder is just string.
Uppercase<T>, Lowercase<T>, Capitalize<T>, Uncapitalize<T> ≥0.316
These four utility types transform the casing of a string type:
-
Uppercase<T>converts every character to upper case. -
Lowercase<T>converts every character to lower case. -
Capitalize<T>converts the first character to upper case, leaving the rest unchanged. -
Uncapitalize<T>converts the first character to lower case, leaving the rest unchanged.
The argument must be a string type. Applied to a string literal type, the result is the transformed literal:
type Greeting = Uppercase<'hello'>; // 'HELLO' 'HELLO' as Greeting; // OK 'hello' as Greeting; // ERROR
type Tag = Lowercase<'WARNING'>; // 'warning' 'warning' as Tag; // OK 'WARNING' as Tag; // ERROR
Capitalize and Uncapitalize only change the first character:
type Name = Capitalize<'flow'>; // 'Flow' 'Flow' as Name; // OK 'flow' as Name; // ERROR 'FLOW' as Name; // ERROR
type Field = Uncapitalize<'FullName'>; // 'fullName' 'fullName' as Field; // OK 'FullName' as Field; // ERROR 'fullname' as Field; // ERROR (the tail is left untouched)
They distribute over union types, transforming each member independently:
type Direction = Uppercase<'north' | 'south'>; // 'NORTH' | 'SOUTH' 'NORTH' as Direction; // OK 'SOUTH' as Direction; // OK 'south' as Direction; // ERROR
You can nest them to compose transformations:
type RoundTrip = Uncapitalize<Capitalize<'foo'>>; 'foo' as RoundTrip; // OK type Nested = Uppercase<Lowercase<'AbC'>>; 'ABC' as Nested; // OK
Applied to the general string type, the result is still a string, but it represents only the strings that are already in the transformed form. A concrete literal must already be in that form to be a member:
type Loud = Uppercase<string>; declare const x: Loud; x as string; // OK 'ANYTHING' as Loud; // OK 'anything' as Loud; // ERROR (not already upper case)
$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:
type InexactUser = {name: string, ...};
type ExactUser = $Exact<InexactUser>;
const user = {name: 'John Wilkes Booth'};
// These will both be satisfied because they are equivalent:
const a: ExactUser = user;
const b: {name: string} = user; Prefer the inverse: define the exact type and spread it into the inexact one.
type ExactUser = {name: string};
type InexactUser = {...ExactUser, ...};
const user = {name: 'John Wilkes Booth'};
const 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
-
Modernizing Legacy Flow Syntax — migrating legacy
$-prefixed utilities such as$ObjMap,$PropertyType, and$NonMaybeTypeto their modern equivalents
© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/types/utilities