CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openapi-typescript-helpers

TypeScript helpers for consuming openapi-typescript types

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

typescript-utilities.mddocs/

TypeScript Utilities

General-purpose TypeScript utility types for advanced type manipulation, conditional type logic, and media type handling.

Capabilities

Key Filtering Utilities

Filter Keys

Find first match of multiple keys from an object type.

/**
 * Find first match of multiple keys
 */
type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];

Usage Examples:

import type { FilterKeys } from "openapi-typescript-helpers";

// Extract values by key pattern
type ApiResponse = {
  "application/json": { data: User };
  "application/xml": string;
  "text/plain": string;
};

// Filter by specific key
type JsonContent = FilterKeys<ApiResponse, "application/json">; // { data: User }

// Filter by key pattern (using template literal types)
type ApplicationTypes = FilterKeys<ApiResponse, `application/${string}`>; 
// { data: User } | string

// Multiple object example
type StatusResponses = {
  200: { success: true };
  400: { error: string };
  404: { error: string };
};

type ErrorResponses = FilterKeys<StatusResponses, 400 | 404>; // { error: string }

Get Value with Default (Deprecated)

Get the type of a value of an input object with a given key, with fallback default.

/**
 * @deprecated Use `FilterKeys` instead
 * Get the type of a value of an input object with a given key. If the key is
 * not found, return a default type. Works with unions of objects too.
 */
type GetValueWithDefault<Obj, KeyPattern, Default> = Obj extends any
  ? FilterKeys<Obj, KeyPattern> extends never
    ? Default
    : FilterKeys<Obj, KeyPattern>
  : never;

Media Type Utilities

Media Type

Return any string/string media type pattern.

/**
 * Return any `[string]/[string]` media type (important because openapi-fetch allows any content response, not just JSON-like)
 */
type MediaType = `${string}/${string}`;

Usage Examples:

import type { MediaType } from "openapi-typescript-helpers";

// Type-safe media type validation
function isValidMediaType(type: string): type is MediaType {
  return /^[^\/]+\/[^\/]+$/.test(type);
}

// Generic content type handling
type ContentTypeMap<T extends MediaType> = {
  [K in T]: unknown;
};

type ApiContent = ContentTypeMap<"application/json" | "text/plain">;
// { "application/json": unknown; "text/plain": unknown }

JSON-Like Media Types

Return media types containing "json".

/**
 * Return any media type containing "json" (works for "application/json", "application/vnd.api+json", "application/vnd.oai.openapi+json")
 */
type JSONLike<T> = FilterKeys<T, `${string}/json`>;

Usage Examples:

import type { JSONLike } from "openapi-typescript-helpers";

// Extract JSON-compatible content types
type ContentTypes = {
  "application/json": { data: User };
  "application/vnd.api+json": { data: User[] };
  "application/xml": string;
  "text/plain": string;
  "text/json": { message: string };
};

type JsonOnlyContent = JSONLike<ContentTypes>; 
// { data: User } | { data: User[] } | { message: string }

// Use in API response handling
function handleJsonResponse<T>(content: JSONLike<T>): void {
  // Only JSON-like content types allowed
}

Required Keys Utilities

Required Keys Helper

Internal helper for required key detection.

/**
 * Helper to get the required keys of an object. If no keys are required, will be `undefined` with strictNullChecks enabled, else `never`
 */
type RequiredKeysOfHelper<T> = {
  [K in keyof T]: {} extends Pick<T, K> ? never : K;
}[keyof T];

Required Keys Of

Get the required keys of an object, or never if no keys are required.

/**
 * Get the required keys of an object, or `never` if no keys are required
 */
type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;

Usage Examples:

import type { RequiredKeysOf } from "openapi-typescript-helpers";

// Check required keys in object types
type User = {
  id: string;
  name: string;
  email?: string;
  profile?: UserProfile;
};

type UserRequiredKeys = RequiredKeysOf<User>; // "id" | "name"

// Use in validation
type ValidateRequired<T, K extends RequiredKeysOf<T>> = {
  [P in K]: T[P];
};

type RequiredUserFields = ValidateRequired<User, RequiredKeysOf<User>>;
// { id: string; name: string }

// Check if object has required fields
type HasRequired<T> = RequiredKeysOf<T> extends never ? false : true;

type UserHasRequired = HasRequired<User>; // true
type EmptyObjectHasRequired = HasRequired<{}>; // false

Deprecated Utilities

Find Required Keys (Deprecated)

Filter objects that have required keys.

/**
 * Filter objects that have required keys
 * @deprecated Use `RequiredKeysOf` instead
 */
type FindRequiredKeys<T, K extends keyof T> = K extends unknown ? (undefined extends T[K] ? never : K) : K;

Has Required Keys (Deprecated)

Check if object contains required keys.

/**
 * Does this object contain required keys?
 * @deprecated Use `RequiredKeysOf` instead
 */
type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;

Migration Examples:

// Old approach (deprecated)
type OldRequiredCheck<T> = HasRequiredKeys<T> extends never ? false : true;

// New approach (recommended)
type NewRequiredCheck<T> = RequiredKeysOf<T> extends never ? false : true;

// Old required key extraction (deprecated)
type OldRequiredKeys<T> = FindRequiredKeys<T, keyof T>;

// New required key extraction (recommended)
type NewRequiredKeys<T> = RequiredKeysOf<T>;

Advanced Usage Patterns

Combining Utilities

import type { 
  FilterKeys, 
  JSONLike, 
  RequiredKeysOf, 
  MediaType 
} from "openapi-typescript-helpers";

// Complex content type filtering
type ApiResponseContent = {
  "application/json": { data: User; meta: Metadata };
  "application/vnd.api+json": { data: User[]; included: Resource[] };
  "application/xml": string;
  "text/html": string;
};

// Extract JSON content and determine required fields
type JsonContent = JSONLike<ApiResponseContent>;
type JsonRequiredKeys = RequiredKeysOf<JsonContent>;

// Create type-safe content handler
type ContentHandler<T extends MediaType> = (
  content: FilterKeys<ApiResponseContent, T>
) => void;

// Use with specific media types
const handleJson: ContentHandler<"application/json"> = (content) => {
  // content is properly typed as { data: User; meta: Metadata }
  console.log(content.data);
};

Error Handling with Utility Types

import type { FilterKeys, RequiredKeysOf } from "openapi-typescript-helpers";

// Create error types with required field validation
type ApiError = {
  code: string;
  message: string;
  details?: Record<string, unknown>;
};

type RequiredErrorFields = RequiredKeysOf<ApiError>; // "code" | "message"

// Ensure error objects have required fields
function createError<T extends Record<RequiredErrorFields, any>>(error: T): T {
  return error;
}

// Type-safe error with all required fields
const validError = createError({
  code: "VALIDATION_ERROR",
  message: "Invalid input provided",
  details: { field: "email" }
});

Install with Tessl CLI

npx tessl i tessl/npm-openapi-typescript-helpers

docs

http-types.md

index.md

openapi-utilities.md

typescript-utilities.md

tile.json