All essential TypeScript types in one place providing 70+ utility types and helper functions.
—
Advanced type operations for merging, transforming, and manipulating complex type structures including dictionaries, unions, and specialized type operations.
Constructs a type that can be either Type or PromiseLike<Type>, useful for functions that can work with both synchronous and asynchronous values.
type AsyncOrSync<Type> = Type | PromiseLike<Type>;Usage Example:
import type { AsyncOrSync } from "ts-essentials";
function processData<T>(data: AsyncOrSync<T>): Promise<T> {
return Promise.resolve(data);
}
// Works with both sync and async values
processData("hello"); // string
processData(Promise.resolve("hello")); // Promise<string>Unwraps AsyncOrSync type to extract the underlying type.
type AsyncOrSyncType<Type> = Type extends PromiseLike<infer U> ? U : Type;Constructs a required object type where property keys are Keys (string by default) and property values are Type.
type Dictionary<Type, Keys extends KeyofBase = string> = {
[key in Keys]: Type;
};Usage Example:
import type { Dictionary } from "ts-essentials";
type StringMap = Dictionary<string>; // { [key: string]: string }
type NumberMap = Dictionary<number, string | number>; // { [key: string | number]: number }
const userRoles: Dictionary<string> = {
admin: "Administrator",
user: "Regular User",
guest: "Guest User"
};Constructs an optional object type where property keys are Keys (string by default) and property values are Type.
type SafeDictionary<Type, Keys extends KeyofBase = string> = {
[key in Keys]?: Type;
};Usage Example:
import type { SafeDictionary } from "ts-essentials";
type OptionalSettings = SafeDictionary<boolean>;
// Result: { [key: string]?: boolean }
const settings: OptionalSettings = {
darkMode: true,
notifications: false
// Other keys are optional
};Constructs a type by picking all properties from Object1 and Object2. Property values from Object2 override property values from Object1 when property keys are the same.
type Merge<Object1, Object2> = Prettify<Omit<Object1, keyof Object2> & Object2>;Usage Example:
import type { Merge } from "ts-essentials";
type User = { id: number; name: string; email: string; };
type UserUpdate = { name: string; lastLogin: Date; };
type UpdatedUser = Merge<User, UserUpdate>;
// Result: { id: number; email: string; name: string; lastLogin: Date; }Constructs a type by merging objects in tuple Tuple recursively using the Merge type.
type MergeN<Tuple extends readonly any[]> = Tuple extends readonly [infer First, ...infer Rest]
? Rest extends readonly any[]
? Merge<First, MergeN<Rest>>
: First
: {};Usage Example:
import type { MergeN } from "ts-essentials";
type Base = { id: number; };
type Named = { name: string; };
type Timed = { createdAt: Date; };
type Entity = MergeN<[Base, Named, Timed]>;
// Result: { id: number; name: string; createdAt: Date; }Constructs a class type with constructor which has return type ReturnType.
type Newable<ReturnType> = new (...args: any[]) => ReturnType;Usage Example:
import type { Newable } from "ts-essentials";
interface Identifiable {
id: string;
}
function createFactory<T extends Identifiable>(ctor: Newable<T>): T {
return new ctor();
}Constructs a type by picking all properties from type Type which values don't equal to never.
type NonNever<Type> = {
[Key in keyof Type as Type[Key] extends never ? never : Key]: Type[Key];
};Usage Example:
import type { NonNever } from "ts-essentials";
type Mixed = {
valid: string;
invalid: never;
alsoValid: number;
alsoInvalid: never;
};
type Cleaned = NonNever<Mixed>;
// Result: { valid: string; alsoValid: number; }Constructs a type by picking all properties from type Type and removing those properties which values equal to Value.
type OmitProperties<Type, Value> = {
[Key in keyof Type as Type[Key] extends Value ? never : Key]: Type[Key];
};Usage Example:
import type { OmitProperties } from "ts-essentials";
type ApiResponse = {
data: string;
error: null;
loading: boolean;
metadata: null;
};
type NonNullFields = OmitProperties<ApiResponse, null>;
// Result: { data: string; loading: boolean; }Constructs a type by picking all properties from type Type which values equal to Value.
type PickProperties<Type, Value> = {
[Key in keyof Type as Type[Key] extends Value ? Key : never]: Type[Key];
};Usage Example:
import type { PickProperties } from "ts-essentials";
type User = {
id: number;
name: string;
email: string;
isActive: boolean;
isAdmin: boolean;
};
type BooleanFields = PickProperties<User, boolean>;
// Result: { isActive: boolean; isAdmin: boolean; }Constructs a type which is a subset of Type with a specified unique token Token. Creates branded/nominal types.
type Opaque<Type, Token> = Type & {
readonly __opaque__: Token;
};Usage Example:
import type { Opaque } from "ts-essentials";
type UserId = Opaque<number, "UserId">;
type ProductId = Opaque<number, "ProductId">;
const userId: UserId = 123 as UserId;
const productId: ProductId = 456 as ProductId;
// This would cause a compile error:
// const wrongId: UserId = productId; // Type error!
function getUserById(id: UserId): User {
// Implementation
}
getUserById(userId); // OK
// getUserById(productId); // Type error!Constructs a path value for type Type and path Path.
type PathValue<Type, Path extends string> = Path extends keyof Type
? Type[Path]
: Path extends `${infer Key}.${infer Rest}`
? Key extends keyof Type
? PathValue<Type[Key], Rest>
: never
: never;Usage Example:
import type { PathValue } from "ts-essentials";
type User = {
profile: {
personal: {
name: string;
age: number;
};
};
};
type UserName = PathValue<User, "profile.personal.name">; // string
type UserAge = PathValue<User, "profile.personal.age">; // numberConstructs a union type by picking all possible paths for type Type.
type Paths<Type> = Type extends Primitive
? never
: {
[Key in keyof Type]: Key extends string
? Type[Key] extends Primitive
? Key
: Key | `${Key}.${Paths<Type[Key]>}`
: never;
}[keyof Type];Usage Example:
import type { Paths } from "ts-essentials";
type User = {
id: number;
profile: {
name: string;
settings: {
theme: string;
};
};
};
type UserPaths = Paths<User>;
// Result: "id" | "profile" | "profile.name" | "profile.settings" | "profile.settings.theme"Constructs an intersection type from union type Union.
type UnionToIntersection<Union> = (
Union extends any ? (arg: Union) => void : never
) extends (arg: infer Intersection) => void
? Intersection
: never;Usage Example:
import type { UnionToIntersection } from "ts-essentials";
type A = { a: string; };
type B = { b: number; };
type C = { c: boolean; };
type Combined = UnionToIntersection<A | B | C>;
// Result: { a: string; } & { b: number; } & { c: boolean; }
// Which is equivalent to: { a: string; b: number; c: boolean; }Constructs a type for type Type and equals to primitive for primitives, array elements for arrays, function return type for functions, or object property values for objects.
type ValueOf<Type> = Type[keyof Type];Usage Example:
import type { ValueOf } from "ts-essentials";
type User = {
id: number;
name: string;
isActive: boolean;
};
type UserValue = ValueOf<User>; // number | string | boolean
const values: UserValue[] = [123, "Alice", true];Constructs a type which is assignable to either Type1 or Type2 but not both. Supports up to 50 generic types.
type XOR<Type1, Type2> =
| (Type1 & { [K in keyof Type2]?: never })
| (Type2 & { [K in keyof Type1]?: never });Usage Example:
import type { XOR } from "ts-essentials";
type LoginByEmail = { email: string; };
type LoginByUsername = { username: string; };
type LoginCredentials = XOR<LoginByEmail, LoginByUsername>;
// Valid:
const emailLogin: LoginCredentials = { email: "user@example.com" };
const usernameLogin: LoginCredentials = { username: "user123" };
// Invalid (would cause compile error):
// const invalidLogin: LoginCredentials = { email: "user@example.com", username: "user123" };/** @deprecated Use ValueOf instead */
type DictionaryValues<Type> = Type[keyof Type];Install with Tessl CLI
npx tessl i tessl/npm-ts-essentials