Skip to main content

typing-generic-responses

Defines generic types for cross-boundary data: ApiResponse<T>, Paginated<T>, Result<T,E>, Repository<T,ID>. Use when designing HTTP responses, use-case return types, or persistence ports.

Source facts

Repository
j4flmao/agent_skills_nodejs_nestjs
Last source activity
May 3, 2026 at 03:46
Detected SKILL.md language
English
Stars
1
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
3 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
typing-generic-responses
description
Defines generic types for cross-boundary data: ApiResponse<T>, Paginated<T>, Result<T,E>, Repository<T,ID>. Use when designing HTTP responses, use-case return types, or persistence ports.
# Typing Generic Responses ## When to use - Designing HTTP response shapes - Defining use-case return types - Creating persistence ports (Repository interfaces) ## Core rules 1. `ApiResponse<T>` for all HTTP responses (success + error envelope) 2. `Result<T,E>` for use-case outputs (typed success/error without throwing) 3. `Paginated<T>` for list endpoint responses 4. `Repository<T,ID>` generic interface for persistence ports 5. All cross-boundary types are explicit, no `any` or `object` ## Reference shape (TypeScript) ### ApiResponse<T> ```typescript export interface ApiResponse<T = unknown> { readonly success: boolean; readonly data?: T; readonly error?: { code: string; message: string; details?: Record<string, unknown> }; readonly metadata?: { timestamp: string; traceId: string }; } ``` ### Result<T,E> ```typescript export type Result<T, E extends AppError = AppError> = | { readonly success: true; readonly value: T } | { readonly success: false; readonly error: E }; export const ok = <T>(value: T): Result<T, never> => ({ success: true, value }); export const err = <E extends AppError>(error: E): Result<never, E> => ({ success: false, error }); ``` ### Repository<T,ID> ```typescript export interface Repository<T, ID> { findById(id: ID): Promise<T | null>; save(entity: T): Promise<T>; deleteById(id: ID): Promise<boolean>; } ``` ## Examples — Do ```typescript // Use-case returns Result async execute(id: string): Promise<Result<User, NotFoundError>> { const user = await this.repo.findById(id); return user ? ok(user) : err(new NotFoundError('User', id)); } ``` ## Examples — Don't ```typescript // ❌ No typing async findUser(id: string): Promise<any> { ... } // ❌ Direct HTTP response from use-case return res.status(200).json({ data: user }); ``` ## Checklist - [ ] `ApiResponse<T>` used for all HTTP responses - [ ] `Result<T,E>` used for use-case returns - [ ] `Repository<T,ID>` generic interface defined - [ ] No `any` in cross-boundary types See [reference/generic-patterns.md](./reference/generic-patterns.md) for full patterns.
View on GitHub