@ethanresnick/utility-types
v3.7.0
Published
Utility Types Collection for TypeScript
Downloads
7
Maintainers
Readme
utility-types
Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).
Found it useful? Want more updates? Show your support by giving a :star:
TypeScript compatibility notes
- v1 - minimum TS v2.7.2
- v2 - minimum TS v2.8.1 (rewritten to conditional types)
- v3 - minimum TS v3.1.0
Motivation
The primary goal of this library is to provide a set of proven Utility Types that should complement existing TypeScript Mapped Types.
The secondary goal is to provide a few additional utility types compatible with Flow's Utility Types helping with gradual migration between "Flow" and "TypeScript" projects.
Goals
- provide a set of consistent Utility Types that are idiomatic and complementary to existing TypeScript Mapped Types
- provide migration from Flow's Utility Types
- clean idiomatic implementation based on composition of smaller generic types that are easy to follow and learn how they work
Features
- Thoroughly tested for type correctness with type-testing library
dts-jest
- Safe with minimal footprint - no third-party dependencies
- No runtime cost - it's type-level only
Installation
npm install --save utility-types
Contributing Guide
We are open for contributions. If you're planning to contribute please make sure to read the contributing guide: CONTRIBUTING.md
Sponsor
Utility-Types is an independent open-source project created by people investing their free time for the benefit of our community.
If you are using Utility-Types please consider donating as this will guarantee the project will be updated and maintained in the long run.
Issues can be funded by anyone and the money will be transparently distributed to the contributors handling a particular issue.
- (built-in) - types built-in TypeScript, no need to import
Table of Contents
Aliases
Type Guards
Union operators
SetIntersection<A, B>
SetDifference<A, B>
SetComplement<A, A1>
SymmetricDifference<A, B>
Exclude<A, B>
(built-in)Extract<A, B>
(built-in)NonNullable<T>
(built-in)NonUndefined<T>
Object operators
FunctionKeys<T>
NonFunctionKeys<T>
ReadonlyKeys<T>
WritableKeys<T>
RequiredKeys<T>
Optional<T, K>
OptionalKeys<T>
ElementsOrKeys<T>
Partial<T>
(built-in)DeepPartial<T>
Required<T>
(built-in)DeepRequired<T>
Readonly<T>
(built-in)DeepReadonly<T>
Pick<T, K>
(built-in)Omit<T, K>
(built-in)PickByValue<T, ValueType>
PickByValueExact<T, ValueType>
OmitByValue<T, ValueType>
OmitByValueExact<T, ValueType>
Intersection<T, U>
Diff<T, U>
Subtract<T, T1>
Overwrite<T, U>
Assign<T, U>
Values<T>
Special operators
ReturnType<T>
(built-in)InstanceType<T>
(built-in)PromiseType<T>
Unionize<T>
Brand<T, U>
SameType<T,U>
Flow's Utility Types
$Keys<T>
$Values<T>
$ReadOnly<T>
$Diff<T, U>
$PropertyType<T, K>
$ElementType<T, K>
$Call<T>
$Shape<T>
$NonMaybeType<T>
Class<T>
mixed
Deprecated API (use at own risk)
getReturnOfExpression()
- from TS v2.0 it's better to use type-levelReturnType
instead
Primitive
Type representing primitive types in JavaScript, and thus TypeScript: number | bigint | boolean | string | symbol
You can test for singular of these types with typeof
Falsey
Type representing falsey values in TypeScript: null | undefined | false | 0 | ''
Except
NaN
which cannot be represented as a type literal
isPrimitive
This is a TypeScript Typeguard for the Primitive
type.
This can be useful to control the type of a parameter as the program flows. Example:
const consumer = (param: Primitive[] | Primitive): string => {
if (isPrimitive(param)) {
// typeof param === Primitive
return String(param) + ' was Primitive';
}
// typeof param === Primitive[]
const resultArray = param
.map(consumer)
.map(rootString => '\n\t' + rootString);
return resultArray.reduce((comm, newV) => comm + newV, 'this was nested:');
};
isFalsey
As isPrimitive
but for the type Falsey
.
SetIntersection<A, B>
(same as Extract)
Set intersection of given union types A
and B
Usage:
import { SetIntersection } from 'utility-types';
// Expect: "2" | "3"
type ResultSet = SetIntersection<'1' | '2' | '3', '2' | '3' | '4'>;
// Expect: () => void
type ResultSetMixed = SetIntersection<string | number | (() => void), Function>;
SetDifference<A, B>
(same as Exclude)
Set difference of given union types A
and B
Usage:
import { SetDifference } from 'utility-types';
// Expect: "1"
type ResultSet = SetDifference<'1' | '2' | '3', '2' | '3' | '4'>;
// Expect: string | number
type ResultSetMixed = SetDifference<string | number | (() => void), Function>;
SetComplement<A, A1>
Set complement of given union types A
and (it's subset) A1
Usage:
import { SetComplement } from 'utility-types';
// Expect: "1"
type ResultSet = SetComplement<'1' | '2' | '3', '2' | '3'>;
SymmetricDifference<A, B>
Set difference of union and intersection of given union types A
and B
Usage:
import { SymmetricDifference } from 'utility-types';
// Expect: "1" | "4"
type ResultSet = SymmetricDifference<'1' | '2' | '3', '2' | '3' | '4'>;
NonNullable<A>
Exclude null
and undefined
from set A
NonUndefined<A>
Exclude undefined
from set A
Exclude<A, B>
Exclude subset B
from set A
Extract<A, B>
Extract subset B
from set A
Operations on objects
FunctionKeys<T>
Get union type of keys that are functions in object type T
Usage:
import { FunctionKeys } from 'utility-types';
type MixedProps = { name: string; setName: (name: string) => void };
// Expect: "setName"
type FunctionKeysProps = FunctionKeys<MixedProps>;
NonFunctionKeys<T>
Get union type of keys that are non-functions in object type T
Usage:
import { NonFunctionKeys } from 'utility-types';
type MixedProps = { name: string; setName: (name: string) => void };
// Expect: "name"
type NonFunctionKeysProps = NonFunctionKeys<MixedProps>;
ReadonlyKeys<T>
Get union type of keys that are readonly in object type T
Usage:
import { ReadonlyKeys } from 'utility-types';
type Props = { readonly foo: string; bar: number };
// Expect: "foo"
type ReadonlyProps = ReadonlyKeys<Props>;
WritableKeys<T>
Get union type of keys that are writable (not readonly) in object type T
Usage:
import { WritableKeys } from 'utility-types';
type Props = { readonly foo: string; bar: number };
// Expect: "bar"
type WritableProps = WritableKeys<Props>;
RequiredKeys<T>
Get union type of keys that are required in object type T
Usage:
import { RequiredKeys } from 'utility-types';
type Props = { req: number; reqUndef: number | undefined; opt?: string; optUndef?: number | undefined; };
// Expect: "req" | "reqUndef"
type RequiredProps = ReadonlyKeys<Props>;
Optional<T, K>
From T
make a set of properties by key K
become optional
Usage:
import { Optional } from 'utility-types';
type Props = { name: string; age: number; visilbe: boolean; };
// Expect: { name?: string; age?: number; visilbe?: boolean; }
type Props = Optional<Props>
// Expect: { name: string; age?: number; visilbe?: boolean; }
type Props = Optional<Props, 'age' | 'visilbe'>;
OptionalKeys<T>
Get union type of keys that are optional in object type T
Usage:
import { OptionalKeys } from 'utility-types';
type Props = { req: number; reqUndef: number | undefined; opt?: string; optUndef?: number | undefined; };
// Expect: "opt" | "optUndef"
type OptionalProps = OptionalKeys<Props>;
ElementsOrKeys<T>
Get the keys of an object type T
, or the elements (i.e., value-holding numeric indices) of a tuple type (as strings).
type Obj = { req: number; reqUndef: number | undefined; opt?: string; };
type Tuple = [number, number | undefined, string];
// Expect: "req" | "reqUndef" | "opt"
type ElementsOrKeys = OptionalKeys<Obj>;
// Expect: "0" | "1" | "2"
type ElementsOrKeys = OptionalKeys<Tuple>;
Pick<T, K>
(built-in)
From T
pick a set of properties by key K
Usage:
type Props = { name: string; age: number; visible: boolean };
// Expect: { age: number; }
type Props = Pick<Props, 'age'>;
PickByValue<T, ValueType>
From T
pick a set of properties by value matching ValueType
.
(Credit: Piotr Lewandowski)
Usage:
import { PickByValue } from 'utility-types';
type Props = { req: number; reqUndef: number | undefined; opt?: string; };
// Expect: { req: number }
type Props = PickByValue<Props, number>;
// Expect: { req: number; reqUndef: number | undefined; }
type Props = PickByValue<Props, number | undefined>;
PickByValueExact<T, ValueType>
From T
pick a set of properties by value matching exact ValueType
.
Usage:
import { PickByValueExact } from 'utility-types';
type Props = { req: number; reqUndef: number | undefined; opt?: string; };
// Expect: { req: number }
type Props = PickByValueExact<Props, number>;
// Expect: { reqUndef: number | undefined; }
type Props = PickByValueExact<Props, number | undefined>;
KeysByValueExact<T, ValueType>
From T
return a union of keys whose value exactly matches ValueType
.
Usage:
type Props = { req: number; reqUndef: number | undefined; opt?: string; };
// Expect: "req"
type Props = KeysByValueExact<Props, number>;
// Expect: "reqUndef"
type Props = KeysByValueExact<Props, number | undefined>;
Omit<T, K>
From T
remove a set of properties by key K
Usage:
import { Omit } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: { name: string; visible: boolean; }
type Props = Omit<Props, 'age'>;
OmitByValue<T, ValueType>
From T
remove a set of properties by value matching ValueType
.
(Credit: Piotr Lewandowski)
Usage:
import { OmitByValue } from 'utility-types';
type Props = { req: number; reqUndef: number | undefined; opt?: string; };
// Expect: { reqUndef: number | undefined; opt?: string; }
type Props = OmitByValue<Props, number>;
// Expect: { opt?: string; }
type Props = OmitByValue<Props, number | undefined>;
OmitByValueExact<T, ValueType>
From T
remove a set of properties by value matching exact ValueType
.
Usage:
import { OmitByValueExact } from 'utility-types';
type Props = { req: number; reqUndef: number | undefined; opt?: string; };
// Expect: { reqUndef: number | undefined; opt?: string; }
type Props = OmitByValueExact<Props, number>;
// Expect: { req: number; opt?: string }
type Props = OmitByValueExact<Props, number | undefined>;
Intersection<T, U>
From T
pick properties that exist in U
Usage:
import { Intersection } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };
// Expect: { age: number; }
type DuplicatedProps = Intersection<Props, DefaultProps>;
Diff<T, U>
From T
remove properties that exist in U
Usage:
import { Diff } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };
// Expect: { name: string; visible: boolean; }
type RequiredProps = Diff<Props, DefaultProps>;
Subtract<T, T1>
From T
remove properties that exist in T1
(T1
has a subset of the properties of T
)
Usage:
import { Subtract } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };
// Expect: { name: string; visible: boolean; }
type RequiredProps = Subtract<Props, DefaultProps>;
Overwrite<T, U>
From U
overwrite properties to T
Usage:
import { Overwrite } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type NewProps = { age: string; other: string };
// Expect: { name: string; age: string; visible: boolean; }
type ReplacedProps = Overwrite<Props, NewProps>;
Assign<T, U>
From U
assign properties to T
(just like object assign)
Usage:
import { Assign } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type NewProps = { age: string; other: string };
// Expect: { name: string; age: number; visible: boolean; other: string; }
type ExtendedProps = Assign<Props, NewProps>;
Values<T>
Get the union type of all the values in an object, tuple, array or array-like type T
. (This is a more general version of $Values<T>
.)
Usage:
import { Values } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = Values<Props>;
type NumberArray = number[];
// Expect: number
type NumberItems = Values<NumberArray>;
type ReadonlyNumberTuple = readonly [1, 2];
// Expect: 1 | 2
type AnotherNumberUnion = Values<NumberTuple>;
type BinaryArray = Uint8Array;
// Expect: number
type BinaryItems = Values<BinaryArray>;
Partial<T>
Make all properties of object type optional
Required<T>
Make all properties of object type non-optional
Readonly<T>
Make all properties of object type readonly
ReturnType<T>
Obtain the return type of a function
InstanceType<T>
Obtain the instance type of a class
Unionize<T>
Disjoin object to form union of objects, each with single property
Usage:
import { Unionize } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: { name: string; } | { age: number; } | { visible: boolean; }
type UnionizedType = Unionize<Props>;
PromiseType<T>
Obtain Promise resolve type
Usage:
import { PromiseType } from 'utility-types';
// Expect: string
type Response = PromiseType<Promise<string>>;
DeepReadonly<T>
Readonly that works for deeply nested structures
Usage:
import { DeepReadonly } from 'utility-types';
type NestedProps = {
first: {
second: {
name: string;
};
};
};
// Expect: {
// readonly first: {
// readonly second: {
// readonly name: string;
// };
// };
// }
type ReadonlyNestedProps = DeepReadonly<NestedProps>;
DeepRequired<T>
Required that works for deeply nested structures
Usage:
import { DeepRequired } from 'utility-types';
type NestedProps = {
first?: {
second?: {
name?: string;
};
};
};
// Expect: {
// first: {
// second: {
// name: string;
// };
// };
// }
type RequiredNestedProps = DeepRequired<NestedProps>;
DeepNonNullable<T>
NonNullable that works for deeply nested structure
Usage:
import { DeepNonNullable } from 'utility-types';
type NestedProps = {
first?: null | {
second?: null | {
name?: string | null | undefined;
};
};
};
// Expect: {
// first: {
// second: {
// name: string;
// };
// };
// }
type RequiredNestedProps = DeepNonNullable<NestedProps>;
DeepPartial<T>
Partial that works for deeply nested structures
Usage:
import { DeepPartial } from 'utility-types';
type NestedProps = {
first: {
second: {
name: string;
};
};
};
// Expect: {
// first?: {
// second?: {
// name?: string;
// };
// };
// }
type PartialNestedProps = DeepPartial<NestedProps>;
Brand<T, U>
Define nominal type of U
based on type of T
.
Usage:
import { Brand } from 'utility-types';
type USD = Brand<number, "USD">
type EUR = Brand<number, "EUR">
const tax = 5 as USD;
const usd = 10 as USD;
const eur = 10 as EUR;
function gross(net: USD): USD {
return (net + tax) as USD;
}
gross(usd); // ok
gross(eur); // Type '"EUR"' is not assignable to type '"USD"'.
SameType<T, U>
Produces true
or false
depending on whether T and U are identical types.
Usage:
import { SameType } from 'utility-types';
type A = SameType<number, number> // true
type B = SameType<number, number | string> // false
type C = SameType<object, boolean> // false
Flow's Utility Types
$Keys<T>
get the union type of all the keys in an object type T
https://flow.org/en/docs/types/utilities/#toc-keys
Usage:
import { $Keys } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: "name" | "age" | "visible"
type PropsKeys = $Keys<Props>;
$Values<T>
get the union type of all the values in an object type T
https://flow.org/en/docs/types/utilities/#toc-values
Usage:
import { $Values } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = $Values<Props>;
$ReadOnly<T>
get the read-only version of a given object type T
https://flow.org/en/docs/types/utilities/#toc-readonly
Usage:
import { $ReadOnly } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: Readonly<{ name: string; age?: number | undefined; visible: boolean; }>
type ReadOnlyProps = $ReadOnly<Props>;
$Diff<T, U>
get the set difference of a given object types T
and U
(T \ U
)
https://flow.org/en/docs/types/utilities/#toc-diff
Usage:
import { $Diff } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };
// Expect: { name: string; visible: boolean; }
type RequiredProps = $Diff<Props, DefaultProps>;
$PropertyType<T, K>
get the type of property of an object at a given key K
https://flow.org/en/docs/types/utilities/#toc-propertytype
Usage:
import { $PropertyType } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: string
type NameType = $PropertyType<Props, 'name'>;
type Tuple = [boolean, number];
// Expect: boolean
type A = $PropertyType<Tuple, '0'>;
// Expect: number
type B = $PropertyType<Tuple, '1'>;
$ElementType<T, K>
get the type of elements inside of array, tuple or object of type T
, that matches the given index type K
https://flow.org/en/docs/types/utilities/#toc-elementtype
Usage:
import { $ElementType } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: string
type NameType = $ElementType<Props, 'name'>;
type Tuple = [boolean, number];
// Expect: boolean
type A = $ElementType<Tuple, 0>;
// Expect: number
type B = $ElementType<Tuple, 1>;
type Arr = boolean[];
// Expect: boolean
type ItemsType = $ElementType<Arr, number>;
type Obj = { [key: string]: number };
// Expect: number
type Values = $ElementType<Obj, string>;
$Call<T>
get the return type of a given expression type https://flow.org/en/docs/types/utilities/#toc-call
Usage:
import { $Call } from 'utility-types';
// Common use-case
const add = (amount: number) => ({ type: 'ADD' as 'ADD', payload: amount });
type AddAction = $Call<typeof returnOfIncrement>; // { type: 'ADD'; payload: number }
// Examples migrated from Flow docs
type ExtractPropType<T extends { prop: any }> = (arg: T) => T['prop'];
type Obj = { prop: number };
type PropType = $Call<ExtractPropType<Obj>>; // number
// type Nope = $Call<ExtractPropType<{ nope: number }>>; // Error: argument doesn't match `Obj`.
type ExtractReturnType<T extends () => any> = (arg: T) => ReturnType<T>;
type Fn = () => number;
type FnReturnType = $Call<ExtractReturnType<Fn>>; // number
$Shape<T>
Copies the shape of the type supplied, but marks every field optional. https://flow.org/en/docs/types/utilities/#toc-shape
Usage:
import { $Shape } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
// Expect: Partial<Props>
type PartialProps = $Shape<Props>;
$NonMaybeType<T>
Converts a type T
to a non-maybe type. In other words, the values of $NonMaybeType<T>
are the values of T
except for null
and undefined
.
https://flow.org/en/docs/types/utilities/#toc-nonmaybe
Usage:
import { $NonMaybeType } from 'utility-types';
type MaybeName = string | null;
// Expect: string
type Name = $NonMaybeType<MaybeName>;
Class<T>
Given a type T representing instances of a class C, the type Class is the type of the class C
https://flow.org/en/docs/types/utilities/#toc-class
* Differs from original Flow's util - implements only constructor part and won't include any static members. Additionally classes in Typescript are not treated as nominal
Usage:
import { Class } from 'utility-types';
function makeStore(storeClass: Class<Store>): Store {
return new storeClass();
}
mixed
An arbitrary type that could be anything (same as unknown
)
https://flow.org/en/docs/types/mixed
Related Projects
ts-toolbelt
- Higher type safety for TypeScript
MIT License
Copyright (c) 2016 Piotr Witek mailto:[email protected] (http://piotrwitek.github.io)