Skip to content

meluiz/typomoon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Typommon

A comprehensive TypeScript utility type library providing essential type helpers for modern TypeScript development.

Table of Contents

Description

Typommon is a lightweight TypeScript library that offers a curated collection of utility types designed to enhance type safety and developer experience. The library focuses on practical type transformations that are commonly needed in real-world TypeScript applications, covering string manipulation, object transformations, number handling, and type composition utilities.

Installation

bun add --dev typommon
# or
npm install --save-dev typommon

Quick Start

import type { 
  PartialBy, 
  Prettify, 
  Numeric, 
  Alphanumeric 
} from 'typommon';

// Make specific fields optional for updates
type User = { id: string; name: string; email: string };
type UserUpdate = PartialBy<User, 'name' | 'email'>;
// Result: { id: string; name?: string; email?: string }

// Clean up complex intersection types
type Complex = { id: string } & { createdAt: Date } & { updatedAt: Date };
type Clean = Prettify<Complex>;
// Better IntelliSense and readability

// Handle both numbers and bigints
function processValue(value: Numeric): string {
  return value.toString();
}

// Validate alphanumeric input
function isValidId(id: string): id is Alphanumeric {
  return /^[A-Za-z0-9]+$/.test(id);
}

Usage

String Types

Character Types

import type { LetterUppercase, LetterLowercase, DigitCharacter, Alphanumeric } from 'typommon';

// Uppercase letters - useful for constants, enums, or validation
const firstLetter: LetterUppercase = 'A'; // ✅ Valid
const invalid: LetterUppercase = 'a'; // ❌ TypeScript error

// Lowercase letters - great for case-sensitive operations
const code: LetterLowercase = 'g'; // ✅ Valid

// Digit characters - perfect for parsing or validation
const seventh: DigitCharacter = '7'; // ✅ Valid

// Alphanumeric characters - ideal for ID validation, tokens, etc.
function isAlphanumeric(char: string): char is Alphanumeric {
  return /[A-Za-z0-9]/.test(char);
}

// Real-world example: validating user input
function validateUsername(username: string): boolean {
  return username.split('').every(char => isAlphanumeric(char));
}

String Utilities

import type { Writable } from 'typommon';

// Remove readonly modifiers - useful when you need to mutate objects
type Config = { readonly id: string; readonly flag: boolean };
type MutableConfig = Writable<Config>;
// Result: { id: string; flag: boolean }

// Real-world example: creating a mutable copy of immutable data
type ImmutableUser = { readonly id: string; readonly name: string; readonly email: string };
type EditableUser = Writable<ImmutableUser>;

function updateUser(user: EditableUser, updates: Partial<EditableUser>): EditableUser {
  return { ...user, ...updates }; // Now we can spread and modify
}

Number Types

import type { Numeric, Zero, NumberSafe } from 'typommon';

// Generic numeric operations - works with both number and bigint
function double(value: Numeric): Numeric {
  return typeof value === 'bigint' ? value * 2n : value * 2;
}

double(10);     // 20
double(10n);    // 20n

// Zero type checking - useful for validation and guards
function isZero(value: Numeric): value is Zero {
  return value === 0 || value === 0n;
}

// Safe number parsing - perfect for form inputs and API responses
function parseSafeNumber(value: NumberSafe): number {
  return typeof value === 'string' ? parseFloat(value) : value;
}

parseSafeNumber("42");  // 42
parseSafeNumber(42);    // 42

// Real-world example: handling user input from forms
function processFormData(data: { count: NumberSafe; price: NumberSafe }) {
  const count = parseSafeNumber(data.count);
  const price = parseSafeNumber(data.price);
  return { count, price, total: count * price };
}

Object Types

Partial Utilities

import type { 
  PartialBy, 
  PartialDeep, 
  PartialExcept, 
  PartialNullable, 
  PartialNullableBy, 
  PartialWithUndefined 
} from 'typommon';

// Make specific keys optional - perfect for update operations
type User = { id: string; email: string; name: string };
type UserDraft = PartialBy<User, 'email' | 'name'>;
// Result: { id: string; email?: string; name?: string }

// Real-world example: API update endpoint
function updateUser(id: string, updates: UserDraft): User {
  // Only email and name can be optional, id is always required
  return { id, ...updates } as User;
}

// Deep partial (recursive) - great for nested object updates
type Settings = { theme: { mode: 'light' | 'dark'; accent: string } };
type SettingsPatch = PartialDeep<Settings>;
// Result: { theme?: { mode?: 'light' | 'dark'; accent?: string } }

// Partial except specific keys - ensure critical fields stay required
type MandatoryId = PartialExcept<User, 'id'>;
// Result: { id: string; email?: string; name?: string }

// Partial with null support - useful for database updates
type Profile = { bio: string; avatar: string };
type ProfilePatch = PartialNullable<Profile>;
// Result: { bio?: string | null; avatar?: string | null }

// Real-world example: clearing optional fields
function clearProfileField(profile: Profile, field: keyof ProfilePatch) {
  return { ...profile, [field]: null };
}

// Partial nullable for specific keys - selective null handling
type Editable = PartialNullableBy<Profile, 'bio' | 'avatar'>;
// Result: { bio?: string | null; avatar?: string | null }

// Partial with explicit undefined - distinguish between omitted and undefined
type Flags = { featureA: boolean; featureB: boolean };
type FlagsPatch = PartialWithUndefined<Flags>;
// Result: { featureA?: boolean | undefined; featureB?: boolean | undefined }

Type Prettification

import type { Prettify, Simplify, Expand } from 'typommon';

// Force TypeScript to display properties as plain object - improves IntelliSense
type WithMeta = { id: string } & { createdAt: Date };
type Readable = Prettify<WithMeta>;
// Result: { id: string; createdAt: Date }

// Real-world example: complex intersection types become readable
type BaseUser = { id: string; name: string };
type WithTimestamps = { createdAt: Date; updatedAt: Date };
type WithPermissions = { role: 'admin' | 'user'; permissions: string[] };

type User = Prettify<BaseUser & WithTimestamps & WithPermissions>;
// Clean IntelliSense instead of complex intersection

// Alias for compatibility with other libraries
type Simplified = Simplify<WithMeta>;

// Expand for variant types - great for discriminated unions
type Variant<T> = Expand<T & { kind: 'variant' }>;
type SuccessVariant = Variant<{ data: string }>;
// Result: { data: string; kind: 'variant' }

Object Utilities

import type { 
  Dict, 
  DeepRequired, 
  Merge, 
  Assign, 
  KeysOfType 
} from 'typommon';

// String-keyed dictionary - perfect for lookup tables and caches
type UserLookup = Dict<{ id: string; name: string }>;
// Result: { [key: string]: { id: string; name: string } }

// Real-world example: user cache
const userCache: UserLookup = {
  'user1': { id: '1', name: 'John' },
  'user2': { id: '2', name: 'Jane' }
};

// Deep required (recursive) - normalize partial data
type MaybeConfig = { theme?: { mode?: string; accent?: string } };
type StrictConfig = DeepRequired<MaybeConfig>;
// Result: { theme: { mode: string; accent: string } }

// Real-world example: API response normalization
function normalizeConfig(partial: MaybeConfig): StrictConfig {
  return {
    theme: {
      mode: partial.theme?.mode ?? 'light',
      accent: partial.theme?.accent ?? '#000000'
    }
  };
}

// Object merging - U overrides T properties
type Base = { id: string; role: 'user'; name: string };
type Override = { role: 'admin'; permissions: string[] };
type Result = Merge<Base, Override>;
// Result: { id: string; role: 'admin'; name: string; permissions: string[] }

// Object assignment - same as Merge, different naming
type Extra = { email: string; phone?: string };
type Assigned = Assign<Base, Extra>;
// Result: { id: string; role: 'user'; name: string; email: string; phone?: string }

// Keys of specific type - extract keys with specific value types
type User = { id: string; age: number; active: boolean; name: string };
type BooleanKeys = KeysOfType<User, boolean>;
// Result: 'active'

// Real-world example: form field validation
function validateBooleanFields<T>(obj: T, fields: KeysOfType<T, boolean>[]): boolean {
  return fields.every(field => typeof obj[field] === 'boolean');
}

API Reference

String Types

Type Description Use Case
LetterUppercase Uppercase ASCII letters (A-Z) Constants, enums, validation
LetterLowercase Lowercase ASCII letters (a-z) Case-sensitive operations
DigitCharacter Single digit characters (0-9) Parsing, validation
Alphanumeric Union of letters and digits ID validation, tokens
Writable<T> Removes readonly modifiers from T Object mutation, cloning

Number Types

Type Description Use Case
Numeric Union of number and bigint Generic numeric operations
Zero Literal zero (0 | 0n) Zero validation, guards
NumberSafe Number or string representation Form inputs, API responses

Object Types

Partial Utilities

Type Description Use Case
PartialBy<T, K> Makes selected keys optional Update operations, drafts
PartialDeep<T> Recursively makes all properties optional Nested object updates
PartialExcept<T, K> Makes all properties optional except selected keys Required field preservation
PartialNullable<T> Makes properties optional and nullable Database updates, clearing fields
PartialNullableBy<T, K> Makes selected keys optional and nullable Selective null handling
PartialWithUndefined<T> Makes properties optional with explicit undefined Serialization, API contracts

Type Prettification

Type Description Use Case
Prettify<T> Forces TypeScript to display as plain object IntelliSense improvement
Simplify<T> Alias for Prettify Library compatibility
Expand<T> Alias for Prettify Variant types, discriminated unions

Object Utilities

Type Description Use Case
Dict<T> String-keyed dictionary type Lookup tables, caches
DeepRequired<T> Recursively makes all properties required Data normalization
Merge<T, U> Merges objects with U overriding T Object composition
Assign<T, U> Alias for Merge Object assignment semantics
KeysOfType<T, U> Extracts keys with values of type U Type-safe field operations

License

MIT

Author

meluiz - me@meluiz.com

Repository

GitHub

About

A comprehensive TypeScript utility type library providing essential type helpers for modern TypeScript development.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors