@ethanresnick/utility-types
TypeScript icon, indicating that this package has built-in type declarations

3.7.0 • Public • Published

utility-types

Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).

Latest Stable Version Build Status Dependency Status peerDependency Status License

NPM Downloads NPM Downloads

Found it useful? Want more updates? Show your support by giving a

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.

Let's fund issues in this repository


  • (built-in) - types built-in TypeScript, no need to import

Table of Contents

Aliases

Type Guards

Union operators

Object operators

Special operators

Flow's Utility Types

Deprecated API (use at own risk)

  • getReturnOfExpression() - from TS v2.0 it's better to use type-level ReturnType 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

⇧ back to top

Falsey

Type representing falsey values in TypeScript: null | undefined | false | 0 | ''

Except NaN which cannot be represented as a type literal

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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'>;

⇧ back to top

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'>;

⇧ back to top

NonNullable<A>

Exclude null and undefined from set A

⇧ back to top

NonUndefined<A>

Exclude undefined from set A

⇧ back to top

Exclude<A, B>

Exclude subset B from set A

⇧ back to top

Extract<A, B>

Extract subset B from set A

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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'>;

⇧ back to top

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

⇧ back to top

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'>;

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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'>;

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

Partial<T>

Make all properties of object type optional

⇧ back to top

Required<T>

Make all properties of object type non-optional

⇧ back to top

Readonly<T>

Make all properties of object type readonly

⇧ back to top

ReturnType<T>

Obtain the return type of a function

⇧ back to top

InstanceType<T>

Obtain the instance type of a class

⇧ back to top

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

⇧ back to top

PromiseType<T>

Obtain Promise resolve type

Usage:

import { PromiseType } from 'utility-types';

// Expect: string
type Response = PromiseType<Promise<string>>;

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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

⇧ back to top

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"'.

⇧ back to top

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

⇧ back to top


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

⇧ back to top

$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>;

⇧ back to top

$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>;

⇧ back to top

$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>;

⇧ back to top

$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'>;

⇧ back to top

$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>;

⇧ back to top

$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

⇧ back to top

$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>;

⇧ back to top

$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>;

⇧ back to top

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();
}

⇧ back to top

mixed

An arbitrary type that could be anything (same as unknown)
https://flow.org/en/docs/types/mixed

⇧ back to top


Related Projects


MIT License

Copyright (c) 2016 Piotr Witek mailto:piotrek.witek@gmail.com (http://piotrwitek.github.io)

Package Sidebar

Install

npm i @ethanresnick/utility-types

Weekly Downloads

50

Version

3.7.0

License

MIT

Unpacked Size

60.7 kB

Total Files

18

Last publish

Collaborators

  • ethanresnick