CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ts-essentials

All essential TypeScript types in one place providing 70+ utility types and helper functions.

Pending
Overview
Eval results
Files

utility-types.mddocs/

Utility Types

Advanced type operations for merging, transforming, and manipulating complex type structures including dictionaries, unions, and specialized type operations.

Capabilities

AsyncOrSync

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>

AsyncOrSyncType

Unwraps AsyncOrSync type to extract the underlying type.

type AsyncOrSyncType<Type> = Type extends PromiseLike<infer U> ? U : Type;

Dictionary

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

SafeDictionary

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

Merge

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

MergeN

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

Newable

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

NonNever

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

OmitProperties

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

PickProperties

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

Opaque

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!

PathValue

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">; // number

Paths

Constructs 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"

UnionToIntersection

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

ValueOf

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

XOR

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

Types

/** @deprecated Use ValueOf instead */
type DictionaryValues<Type> = Type[keyof Type];

Install with Tessl CLI

npx tessl i tessl/npm-ts-essentials

docs

array-tuple-types.md

basic-types.md

change-case-types.md

deep-wrapper-types.md

function-types.md

index.md

key-types.md

mark-wrapper-types.md

type-checkers.md

utility-functions.md

utility-types.md

tile.json