CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ts-toolbelt

TypeScript's largest utility library providing 200+ type utilities for advanced type manipulation.

Pending
Overview
Eval results
Files

union.mddocs/

Union Module

Union type operations including set operations, filtering, transformations, and nullability handling for working with union types effectively.

Capabilities

Set Operations

Core set operations treating unions as mathematical sets.

/**
 * Exclude types from union (set difference)
 * @param U - Union to exclude from
 * @param E - Types to exclude
 * @returns Union without excluded types
 */
type Exclude<U, E> = U extends E ? never : U;

/**
 * Extract types from union (set intersection)
 * @param U - Union to extract from
 * @param E - Types to extract
 * @returns Only extracted types from union
 */
type Extract<U, E> = U extends E ? U : never;

/**
 * Set intersection of two unions
 * @param U1 - First union
 * @param U2 - Second union
 * @returns Types common to both unions
 */
type Intersect<U1, U2> = Extract<U1, U2>;

/**
 * Set difference of two unions
 * @param U1 - First union
 * @param U2 - Second union
 * @returns Types in U1 but not in U2
 */
type Diff<U1, U2> = Exclude<U1, U2>;

Usage Examples:

import { U } from "ts-toolbelt";

type Numbers = 1 | 2 | 3 | 4 | 5;
type EvenNumbers = 2 | 4 | 6 | 8;
type Strings = "a" | "b" | "c";

// Exclude operations
type OddNumbers = U.Exclude<Numbers, EvenNumbers>; // 1 | 3 | 5
type NonStrings = U.Exclude<string | number | boolean, string>; // number | boolean

// Extract operations
type CommonNumbers = U.Extract<Numbers, EvenNumbers>; // 2 | 4
type OnlyStrings = U.Extract<string | number | boolean, string>; // string

// Set operations
type Intersection = U.Intersect<Numbers, EvenNumbers>; // 2 | 4
type Difference = U.Diff<Numbers, EvenNumbers>; // 1 | 3 | 5

// Complex set operations
type Mixed1 = string | number | boolean;
type Mixed2 = string | object | null;
type CommonTypes = U.Intersect<Mixed1, Mixed2>; // string
type UniqueToFirst = U.Diff<Mixed1, Mixed2>; // number | boolean

Union Queries

Query operations to check membership and properties of unions.

/**
 * Check if union contains a specific type
 * @param U - Union to check
 * @param A - Type to look for
 * @returns 1 if type is in union, 0 otherwise
 */
type Has<U, A> = A extends U ? 1 : 0;

/**
 * Get last member of union (implementation-dependent)
 * @param U - Union to get last member from
 * @returns Last union member
 */
type Last<U> = LastImpl<U>;

Usage Examples:

import { U } from "ts-toolbelt";

type Primitives = string | number | boolean;

// Check membership
type HasString = U.Has<Primitives, string>; // 1
type HasObject = U.Has<Primitives, object>; // 0
type HasBoolean = U.Has<Primitives, boolean>; // 1

// Get last member
type LastPrimitive = U.Last<Primitives>; // boolean (implementation-dependent)

// Conditional logic based on membership
type ConditionalType<T> = U.Has<string | number, T> extends 1 
  ? "primitive" 
  : "other";

type Test1 = ConditionalType<string>; // "primitive"
type Test2 = ConditionalType<object>; // "other"

Union Transformations

Transform unions into other forms and manipulate their structure.

/**
 * Make union not allow excess properties (strict object unions)
 * @param U - Union of objects to make strict  
 * @returns Union with strict property checking
 */
type Strict<U extends object> = ComputeRaw<_Strict<U>>;

/**
 * Merge union of object types into single intersection
 * @param U - Union of objects to merge
 * @returns Intersection of all object types
 */
type Merge<U> = MergeImpl<U>;

/**
 * Transform union to intersection type
 * @param U - Union to transform to intersection
 * @returns Intersection of all union members
 */
type IntersectOf<U extends any> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

/**
 * Convert union to list/tuple
 * @param U - Union to convert
 * @returns Tuple containing union members
 */
type ListOf<U> = ListOfImpl<U>;

/**
 * Remove last member from union
 * @param U - Union to pop from
 * @returns Union without last member
 */
type Pop<U> = PopImpl<U>;

/**
 * Replace types in union
 * @param U - Union to replace in
 * @param From - Type to replace
 * @param To - Replacement type
 * @returns Union with replaced types
 */
type Replace<U, From, To> = U extends From ? To : U;

Usage Examples:

import { U } from "ts-toolbelt";

// Union merging
type User = { name: string };
type Profile = { age: number };
type Settings = { theme: string };
type UserUnion = User | Profile | Settings;

type MergedUser = U.Merge<UserUnion>; // { name: string } & { age: number } & { theme: string }

// Union to intersection - useful for function overloads
type Func1 = (a: string) => void;
type Func2 = (a: number) => void;
type UnionFunc = Func1 | Func2;
type IntersectedFunc = U.IntersectOf<UnionFunc>; // (a: string) => void & (a: number) => void

// Strict unions prevent excess properties
type Cat = { type: "cat"; meow: boolean };
type Dog = { type: "dog"; bark: boolean };
type Animal = Cat | Dog;
type StrictAnimal = U.Strict<Animal>; // Prevents { type: "cat"; meow: true; extraProp: any }

// Union to list
type PrimitiveUnion = string | number | boolean;
type PrimitiveList = U.ListOf<PrimitiveUnion>; // [string, number, boolean] (order may vary)

// Replace in union
type Original = "red" | "green" | "blue";
type Updated = U.Replace<Original, "red", "crimson">; // "crimson" | "green" | "blue"

// Pop from union
type Colors = "red" | "green" | "blue";
type FewerColors = U.Pop<Colors>; // "red" | "green" (removes last, implementation-dependent)

// Multiple replacements
type StatusCodes = 200 | 404 | 500;
type UpdatedCodes = U.Replace<U.Replace<StatusCodes, 404, 400>, 500, 503>; // 200 | 400 | 503

Union Filtering

Filter union members based on conditions and criteria.

/**
 * Filter union members based on condition
 * @param U - Union to filter
 * @param M - Filter condition/matcher
 * @returns Union members matching condition
 */
type Filter<U, M> = FilterImpl<U, M>;

/**
 * Select union members based on condition
 * @param U - Union to select from
 * @param C - Selection condition
 * @returns Selected union members
 */
type Select<U, C> = SelectImpl<U, C>;

Usage Examples:

import { U } from "ts-toolbelt";

// Filter by type
type Mixed = string | number | boolean | null | undefined;
type OnlyPrimitives = U.Filter<Mixed, string | number | boolean>; // string | number | boolean
type NoNullish = U.Filter<Mixed, Exclude<Mixed, null | undefined>>; // string | number | boolean

// Select by condition (conceptual - actual implementation varies)
type SelectStrings = U.Select<Mixed, string>; // string
type SelectNumbers = U.Select<Mixed, number>; // number

// Complex filtering
type ObjectTypes = { a: string } | { b: number } | string | number;
type OnlyObjects = U.Filter<ObjectTypes, object>; // { a: string } | { b: number }
type OnlyPrimitiveTypes = U.Filter<ObjectTypes, string | number>; // string | number

Nullability Operations

Handle null and undefined types within unions.

/**
 * Remove null and undefined from union
 * @param U - Union to make non-nullable
 * @returns Union without null or undefined
 */
type NonNullable<U> = U extends null | undefined ? never : U;

/**
 * Add null to union
 * @param U - Union to make nullable
 * @returns Union with null added
 */
type Nullable<U> = U | null;

Usage Examples:

import { U } from "ts-toolbelt";

// Non-nullable operations
type MaybeString = string | null | undefined;
type DefinitelyString = U.NonNullable<MaybeString>; // string

type Optional = number | boolean | null | undefined;
type Required = U.NonNullable<Optional>; // number | boolean

// Make nullable
type Primitives = string | number | boolean;
type NullablePrimitives = U.Nullable<Primitives>; // string | number | boolean | null

// Chain operations
type CleanedUp = U.NonNullable<string | number | null | undefined>; // string | number
type MadeNullable = U.Nullable<CleanedUp>; // string | number | null

// Conditional nullability
type ConditionalNullable<T, MakeNull extends boolean> = 
  MakeNull extends true ? U.Nullable<T> : U.NonNullable<T>;

type WithNull = ConditionalNullable<string | null, true>; // string | null
type WithoutNull = ConditionalNullable<string | null, false>; // string

Practical Applications

Real-world usage patterns for union operations.

Usage Examples:

import { U, O } from "ts-toolbelt";

// API response type handling
type SuccessResponse = { status: "success"; data: any };
type ErrorResponse = { status: "error"; message: string };
type PendingResponse = { status: "pending" };
type ApiResponse = SuccessResponse | ErrorResponse | PendingResponse;

type ErrorStatuses = U.Extract<ApiResponse["status"], "error" | "pending">; // "error" | "pending"
type NonErrorResponse = U.Exclude<ApiResponse, ErrorResponse>; // SuccessResponse | PendingResponse

// Event system
type ClickEvent = { type: "click"; x: number; y: number };
type KeyEvent = { type: "key"; key: string };
type ResizeEvent = { type: "resize"; width: number; height: number };
type Events = ClickEvent | KeyEvent | ResizeEvent;

type EventTypes = Events["type"]; // "click" | "key" | "resize"
type UIEvents = U.Exclude<Events, ResizeEvent>; // ClickEvent | KeyEvent
type OnlyResize = U.Extract<Events, ResizeEvent>; // ResizeEvent

// State management
type LoadingState = { type: "loading" };
type LoadedState = { type: "loaded"; data: any };
type ErrorState = { type: "error"; error: string };
type State = LoadingState | LoadedState | ErrorState;

type StateTypes = State["type"]; // "loading" | "loaded" | "error"
type DataStates = U.Exclude<State, LoadingState>; // LoadedState | ErrorState
type HasData = U.Has<State["type"], "loaded">; // 1

// Form validation
type ValidationError = 
  | { field: "email"; error: "invalid" }
  | { field: "password"; error: "too_short" }
  | { field: "age"; error: "required" };

type ErrorFields = ValidationError["field"]; // "email" | "password" | "age"
type EmailErrors = U.Extract<ValidationError, { field: "email" }>; // { field: "email"; error: "invalid" }
type NonEmailErrors = U.Exclude<ValidationError, { field: "email" }>; // password and age errors

Types

// Union operations work with any union types
// Results maintain the union structure or transform it as specified

Install with Tessl CLI

npx tessl i tessl/npm-ts-toolbelt

docs

any.md

boolean.md

class.md

community.md

function.md

index.md

iteration.md

list.md

misc.md

number.md

object.md

string.md

testing.md

union.md

tile.json