skills / alinaqi / claude-bootstrap / typescript 
typescript 
$ npx skills add https://github.com/alinaqi/claude-bootstrap --skill typescript SKILL.md 
TypeScript Skill 
Load with: base.md 
Strict Mode (Non-Negotiable) 

// tsconfig.json { "compilerOptions" : { "strict" : true , "noImplicitAny" : true , "strictNullChecks" : true , "noUnusedLocals" : true , "noUnusedParameters" : true , "noImplicitReturns" : true , "esModuleInterop" : true , "skipLibCheck" : true , "forceConsistentCasingInFileNames" : true } } 
Project Structure 

project/ ├── src/ │   ├── core/               # Pure business logic │   │   ├── types.ts        # Domain types/interfaces │   │   ├── services/       # Pure functions │   │   └── index.ts        # Public API │   ├── infra/              # Side effects │   │   ├── api/            # HTTP handlers │   │   ├── db/             # Database operations │   │   └── external/       # Third-party integrations │   └── utils/              # Shared utilities ├── tests/ │   ├── unit/ │   └── integration/ ├── package.json ├── tsconfig.json └── CLAUDE.md 
Tooling (Required) 

// package.json scripts { "scripts" : { "lint" : "eslint src/ --ext .ts,.tsx" , "typecheck" : "tsc --noEmit" , "test" : "jest" , "test:coverage" : "jest --coverage" , "format" : "prettier --write 'src/**/*.ts'" } } 

// eslint.config.js import eslint from '@eslint/js' ; import tseslint from 'typescript-eslint' ; export default tseslint . config ( eslint . configs . recommended , ... tseslint . configs . strictTypeChecked , { rules : { '@typescript-eslint/no-explicit-any' : 'error' , '@typescript-eslint/explicit-function-return-type' : 'error' , 'max-lines-per-function' : [ 'error' , 20 ] , 'max-depth' : [ 'error' , 2 ] , 'max-params' : [ 'error' , 3 ] , } } ) ; 
Testing with Jest 

// tests/unit/services/user.test.ts import { calculateTotal } from '../../../src/core/services/pricing' ; describe ( 'calculateTotal' , ( ) => { it ( 'returns sum of item prices' , ( ) => { // Arrange const items = [ { price : 10 } , { price : 20 } ] ; // Act const result = calculateTotal ( items ) ; // Assert expect ( result ) . toBe ( 30 ) ; } ) ; it ( 'returns zero for empty array' , ( ) => { expect ( calculateTotal ( [ ] ) ) . toBe ( 0 ) ; } ) ; it ( 'throws on invalid item' , ( ) => { expect ( ( ) => calculateTotal ( [ { invalid : 'item' } ] ) ) . toThrow ( ) ; } ) ; } ) ; 
GitHub Actions 

name : TypeScript Quality Gate on : [ push , pull_request ] jobs : quality : runs-on : ubuntu - latest steps : - uses : actions/checkout@v4 - name : Setup Node uses : actions/setup - node@v4 with : node-version : '20' - name : Install dependencies run : npm ci - name : Lint run : npm run lint - name : Type Check run : npm run typecheck - name : Test with Coverage run : npm run test : coverage - name : Coverage Threshold (80%) run : npm run test : coverage - - - - coverageThreshold=' { "global" : { "branches" : 80 , "functions" : 80 , "lines" : 80 , "statements" : 80 } } ' 
Pre-Commit Hooks 
Using Husky + lint-staged: 

npm install -D husky lint-staged npx husky init 

// package.json { "lint-staged" : { "*.{ts,tsx}" : [ "eslint --fix" , "prettier --write" ] } } 

# .husky/pre-commit npx lint-staged npx tsc --noEmit npm run test -- --onlyChanged --passWithNoTests 
This runs on every commit: 
ESLint + Prettier on staged files 
Type check entire project 
Tests for changed files only 
Type Patterns 
Discriminated Unions for Results 

type Result < T > = | { ok : true ; value : T } | { ok : false ; error : string } ; function parseUser ( data : unknown ) : Result < User > { // Type-safe error handling without exceptions } 
Branded Types for IDs 

type UserId = string & { readonly brand : unique symbol } ; type OrderId = string & { readonly brand : unique symbol } ; // Can't accidentally pass UserId where OrderId expected function getOrder ( orderId : OrderId ) : Order { ... } 
Const Assertions for Literals 

const STATUSES = [ 'pending' , 'active' , 'closed' ] as const ; type Status = typeof STATUSES [ number ] ; // 'pending' | 'active' | 'closed' 
Zod for Runtime Validation 

import { z } from 'zod' ; const UserSchema = z . object ( { email : z . string ( ) . email ( ) , name : z . string ( ) . min ( 1 ) . max ( 100 ) , } ) ; type User = z . infer < typeof UserSchema > ; 
TypeScript Anti-Patterns 
❌ 
any type - use 
unknown and narrow 
❌ Type assertions ( 
as ) - use type guards 
❌ Non-null assertions ( 
! ) - handle null explicitly 
❌ 
@ts-ignore without explanation 
❌ Enums - use const objects or union types 
❌ Classes for data - use interfaces/types 
❌ Default exports - use named exports Weekly Installs 57 Repository alinaqi/claude-bootstrap First Seen Jan 19, 2026 Security Audits Gen Agent Trust Hub Pass Socket Pass Snyk Pass Installed on claude-code 45 opencode 42 gemini-cli 37 codex 33 cursor 32 antigravity 32