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

key-types.mddocs/

Key Types

Extract and work with object property keys based on their characteristics (optional, required, readonly, writable). These types help you work with the structure and metadata of object types.

Capabilities

OptionalKeys

Constructs a union type by picking all optional properties of object type Type.

type OptionalKeys<Type> = {
  [K in keyof Type]-?: {} extends Pick<Type, K> ? K : never;
}[keyof Type];

Usage Example:

import type { OptionalKeys } from "ts-essentials";

type User = {
  id: number;
  name: string;
  email?: string;
  avatar?: string;
  bio?: string;
};

type UserOptionalKeys = OptionalKeys<User>;
// Result: "email" | "avatar" | "bio"

// Use with Pick to get all optional properties
type OptionalUserProps = Pick<User, OptionalKeys<User>>;
// Result: { email?: string; avatar?: string; bio?: string; }

PickKeys

Constructs a union type by picking all properties of object type Type which values are assignable to type Value.

type PickKeys<Type, Value> = {
  [K in keyof Type]: Type[K] extends Value ? K : never;
}[keyof Type];

Usage Example:

import type { PickKeys } from "ts-essentials";

type User = {
  id: number;
  name: string;
  email: string;
  age: number;
  isActive: boolean;
  isAdmin: boolean;
};

type StringKeys = PickKeys<User, string>;
// Result: "name" | "email"

type BooleanKeys = PickKeys<User, boolean>;
// Result: "isActive" | "isAdmin"

type NumberKeys = PickKeys<User, number>;
// Result: "id" | "age"

// Use with Pick to extract properties by type
type UserStrings = Pick<User, PickKeys<User, string>>;
// Result: { name: string; email: string; }

ReadonlyKeys

Constructs a union type by picking all readonly properties of object type Type.

type ReadonlyKeys<Type> = {
  [K in keyof Type]-?: ReadonlyEquivalent<
    { [Q in K]: Type[K] },
    { -readonly [Q in K]: Type[K] }
  > extends true
    ? never
    : K;
}[keyof Type];

Usage Example:

import type { ReadonlyKeys } from "ts-essentials";

type User = {
  readonly id: number;
  name: string;
  readonly createdAt: Date;
  email: string;
  readonly version: number;
};

type UserReadonlyKeys = ReadonlyKeys<User>;
// Result: "id" | "createdAt" | "version"

// Use with Pick to get all readonly properties
type ReadonlyUserProps = Pick<User, ReadonlyKeys<User>>;
// Result: { readonly id: number; readonly createdAt: Date; readonly version: number; }

RequiredKeys

Constructs a union type by picking all required properties of object type Type.

type RequiredKeys<Type> = {
  [K in keyof Type]-?: {} extends Pick<Type, K> ? never : K;
}[keyof Type];

Usage Example:

import type { RequiredKeys } from "ts-essentials";

type User = {
  id: number;
  name: string;
  email?: string;
  avatar?: string;
  createdAt: Date;
};

type UserRequiredKeys = RequiredKeys<User>;
// Result: "id" | "name" | "createdAt"

// Use with Pick to get all required properties
type RequiredUserProps = Pick<User, RequiredKeys<User>>;
// Result: { id: number; name: string; createdAt: Date; }

// Useful for validation schemas
function validateRequiredFields<T>(
  obj: T,
  requiredKeys: RequiredKeys<T>[]
): boolean {
  return requiredKeys.every(key => obj[key] !== undefined);
}

WritableKeys

Constructs a union type by picking all writable properties of object type Type, meaning their values can be reassigned.

type WritableKeys<Type> = {
  [K in keyof Type]-?: ReadonlyEquivalent<
    { [Q in K]: Type[K] },
    { -readonly [Q in K]: Type[K] }
  > extends true
    ? K
    : never;
}[keyof Type];

Usage Example:

import type { WritableKeys } from "ts-essentials";

type User = {
  readonly id: number;
  name: string;
  email: string;
  readonly createdAt: Date;
  isActive: boolean;
};

type UserWritableKeys = WritableKeys<User>;
// Result: "name" | "email" | "isActive"

// Use with Pick to get all writable properties
type WritableUserProps = Pick<User, WritableKeys<User>>;
// Result: { name: string; email: string; isActive: boolean; }

// Useful for update operations
function updateUser<T>(
  user: T,
  updates: Partial<Pick<T, WritableKeys<T>>>
): T {
  return { ...user, ...updates };
}

Advanced Usage

Combine multiple key type utilities for complex type operations:

import type { RequiredKeys, OptionalKeys, WritableKeys, ReadonlyKeys, PickKeys } from "ts-essentials";

type User = {
  readonly id: number;
  name: string;
  email?: string;
  readonly createdAt: Date;
  isActive: boolean;
  avatar?: string;
};

// Get required writable properties
type RequiredWritableKeys = RequiredKeys<User> & WritableKeys<User>;
// Result: "name" | "isActive"

// Get optional readonly properties  
type OptionalReadonlyKeys = OptionalKeys<User> & ReadonlyKeys<User>;
// Result: never (no properties are both optional and readonly in this example)

// Get all string properties that are writable
type WritableStringKeys = WritableKeys<User> & PickKeys<User, string>;
// Result: "name"

// Create update type with only writable properties
type UserUpdate = Partial<Pick<User, WritableKeys<User>>>;
// Result: { name?: string; email?: string; isActive?: boolean; avatar?: string; }

Types

type ReadonlyEquivalent<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
  ? true
  : false;

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