TypeScript Utility Types Collection
utility-types is a comprehensive collection of TypeScript utility types designed to complement and extend TypeScript's built-in mapped types and aliases. Currently stable at v3.11.0, the library maintains an active release schedule, frequently introducing new type utilities and refining existing ones to keep pace with TypeScript's evolution and community needs. It differentiates itself by offering a broad range of idiomatic types, including those compatible with Flow's utility types to aid migration efforts, all without introducing any runtime cost. The package prides itself on being secure and minimal, having no third-party dependencies and ensuring type correctness through rigorous testing with `dts-jest`. Its primary goal is to provide developers with a robust, zero-cost 'lodash' for static types, eliminating the need to re-implement common type patterns across projects.
Common errors
-
Cannot find name 'Primitive'.
cause A utility type like `Primitive` was used without an explicit `import` statement.fixAdd an import statement for the specific type: `import { Primitive } from 'utility-types';` -
Type 'null' is not assignable to type 'string'.
cause Attempting to assign a `null` or `undefined` value where a non-`Nullish` type is expected, potentially misusing `Falsy` when a stricter `Nullish` or custom union is needed. While `Falsy` includes `null` and `undefined`, specific contexts might expect only non-`Nullish` values.fixEnsure the type you're using (e.g., `Falsy`, `Nullish`) accurately reflects the allowed values. If only `null` or `undefined` are desired, use `Nullish`. For other falsy values, understand the full scope of `Falsy` or define a more precise custom type. -
Property 'someProperty' is readonly and cannot be assigned to in type 'DeepReadonly<T>'.
cause An attempt was made to modify a property of an object wrapped with `DeepReadonly`, which recursively makes all properties immutable.fixIf modification is required, create a mutable copy of the object before applying `DeepReadonly` or work with the original mutable object. If only top-level immutability is needed, use TypeScript's built-in `Readonly<T>`.
Warnings
- breaking utility-types has specific TypeScript version requirements for its major versions. v3.x.x requires TypeScript v3.1+, v2.x.x requires TypeScript v2.8.1+, and v1.x.x requires TypeScript v2.7.2+. Using an incompatible version of TypeScript will likely lead to compilation errors and unexpected type behavior.
- deprecated As of v3.9.0, the type alias `Falsey` has been deprecated in favor of `Falsy`. While `Falsey` is kept for backward compatibility, new code should use `Falsy` to ensure future compatibility and align with the updated naming convention.
- gotcha In v3.6.1, the `Omit` implementation was reverted to an older version due to a bug in TypeScript v3.5. Users upgrading from v3.6.0 or using TypeScript v3.5 might experience subtle changes in `Omit`'s behavior or type inference. It is recommended to update TypeScript to a more recent stable version if possible.
- breaking In v3.10.0, `undefined` was removed from the `keyof` result of `(Pick|Omit)ByValue(Exact)`. This is a type-level breaking change that could alter type inference and assignments for code relying on the previous behavior where `undefined` might have been included in the key types.
- gotcha As a library deeply integrated with TypeScript's evolving type system, even minor version bumps can sometimes introduce subtle breaking changes in type inference or edge-case behavior due to refinements or bug fixes (e.g., changes to `Primitive`, `FunctionKey`, `NonFunctionKeys`). Always review release notes when upgrading, especially for significant minor versions, to understand potential impacts.
Install
-
npm install utility-types -
yarn add utility-types -
pnpm add utility-types
Imports
- DeepReadonly
const DeepReadonly = require('utility-types');import { DeepReadonly } from 'utility-types'; - Optional
import Optional from 'utility-types';
import { Optional } from 'utility-types'; - Falsy
import { Falsey } from 'utility-types';import { Falsy } from 'utility-types'; - Primitive
import { Primitive } from 'utility-types';
Quickstart
import { DeepReadonly, Optional, Falsy, Primitive, Nullish } from 'utility-types';
interface User {
id: number;
name: string;
email?: string;
settings: {
theme: 'dark' | 'light';
notificationsEnabled: boolean;
};
}
// DeepReadonly: Makes all properties, including nested ones, readonly.
type ImmutableUser = DeepReadonly<User>;
const user: ImmutableUser = {
id: 1,
name: 'Alice',
settings: {
theme: 'dark',
notificationsEnabled: true,
},
};
// user.name = 'Bob'; // Error: Cannot assign to 'name' because it is a read-only property.
// user.settings.theme = 'light'; // Error: Cannot assign to 'theme' because it is a read-only property.
// Optional<T, K>: Makes specific keys K in T optional.
type UserWithOptionalId = Optional<User, 'id'>;
const newUser: UserWithOptionalId = {
name: 'Bob',
settings: { theme: 'light', notificationsEnabled: false },
};
// Falsy: Represents common "falsy" values in JavaScript.
function isFalsyValue(value: unknown): value is Falsy {
return !value; // A simple runtime check for demonstration
}
console.log(`Is 0 falsy? ${isFalsyValue(0)}`); // true
console.log(`Is 'hello' falsy? ${isFalsyValue('hello')}`); // false
// Primitive: Represents non-object types.
type MyPrimitive = Primitive;
let p: MyPrimitive = 123;
p = 'hello';
p = true;
// p = { a: 1 }; // Error: Type '{ a: number; }' is not assignable to type 'Primitive'.
// Nullish: Represents null or undefined.
type MaybeString = string | Nullish;
const s1: MaybeString = "hello";
const s2: MaybeString = null;
const s3: MaybeString = undefined;
// const s4: MaybeString = false; // Error: Type 'false' is not assignable to type 'string | null | undefined'.
// This quickstart demonstrates how to use several key utility types from the `utility-types`
// library, including `DeepReadonly` for deep immutability, `Optional` for making specific
// properties optional, and `Falsy`, `Primitive`, and `Nullish` for working with common
// JavaScript value classifications at the type level.