shinpr/ai-coding-project-boilerplate-typescript-rules
Applies type safety and error handling rules. Enforces no-any policy and type guards. Use when implementing TypeScript or reviewing types.
npx skills add https://github.com/shinpr/ai-coding-project-boilerplate --skill typescript-rules
Inspect tsconfig, runtime/framework configuration, lint/format configuration, path aliases, package scripts, and representative modules before applying project conventions. Treat a rule as project-specific only when configuration or an established pattern supports it. Label limited-pattern conclusions as inferred. When competing conventions change a public contract, runtime behavior, or error boundary, stop and name the source or user decision required.
Type Safety in Data Flow
Input Layer (unknown) -> Type Guard -> Business Layer (Type Guaranteed) -> Output Layer (Serialization)
Backend-Specific Type Scenarios:
unknown and validate them with type guardsunknown, type determined after validationunknown; isolate any evidence-backed assertion in the adapter that owns the boundaryPartial<T> for intentionally partial fixtures and typed vi.fn<[Args], Return>() only when Vitest is configuredClass Usage Criteria
// Functions and interfaces
interface UserService { create(data: UserData): User }
const userService: UserService = { create: (data) => {...} }
Function Design
// Object parameter
function createUser({ name, email, role }: CreateUserParams) {}
Dependency Injection
// Receive dependency as parameter
function createService(repository: Repository) { return {...} }
Asynchronous Processing
async/await when it makes sequencing and error propagation explicittry-catch when the current layer can convert, enrich, recover, or record the failure. Otherwise allow the promise rejection to propagate to the owning boundaryPromise<Result>)Format Rules
PascalCase, variables/functions in camelCasetsconfig or the configured build tool; otherwise use relative importsClean Code Principles
console.log()Error Outcome Rule: Every failure has one owning outcome: return a typed expected error, recover according to a named requirement, or propagate it with diagnostic context. Log at the observability-owning boundary so one failure is not logged repeatedly.
Fail-Fast Principle: Fail quickly on errors to prevent continued processing in invalid states
// Invalid: fallback hides a failure required by the caller
catch (error) {
return defaultValue // Hides error
}
// Explicit propagation with added context
catch (error) {
throw new Error('Processing failed', { cause: error })
}
Result Type Pattern: Express errors with types for explicit handling
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
// Example: Express error possibility with types
function parseUser(data: unknown): Result<User, ValidationError> {
if (!isValid(data)) return { ok: false, error: new ValidationError() }
return { ok: true, value: data as User }
}
Custom Error Classes
export class AppError extends Error {
constructor(message: string, public readonly code: string, public readonly statusCode = 500) {
super(message)
this.name = this.constructor.name
}
}
// Purpose-specific: ValidationError(400), BusinessRuleError(400), DatabaseError(500), ExternalServiceError(502)
Layer-Specific Error Handling (Backend)
Structured Logging and Sensitive Information Protection
Log only fields approved for the current trust boundary. Redact credentials, tokens, secrets, payment data, and personal data before logging.
Asynchronous Error Handling
unhandledRejection/uncaughtException handling at the application entry point when the runtime exposes those events; libraries leave process-level policy to their hostTake shinpr/ai-coding-project-boilerplate-typescript-rules from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.