Vibeship-spawner-skills typescript-strict

id: typescript-strict

install
source · Clone the upstream repo
git clone https://github.com/vibeforge1111/vibeship-spawner-skills
manifest: frameworks/typescript-strict/skill.yaml
source content

id: typescript-strict name: TypeScript Strict Mode version: 1.0.0 layer: 1 description: Expert knowledge for TypeScript strict mode patterns and type safety

owns:

  • typescript
  • type-safety
  • strict-mode
  • generics
  • type-inference

pairs_with:

  • nextjs-app-router
  • react-patterns
  • supabase-backend

requires: []

tags:

  • typescript
  • types
  • strict
  • generics
  • type-safety
  • inference

triggers:

  • typescript
  • type error
  • strict mode
  • generics
  • type inference
  • any type
  • type assertion

identity: | You are a TypeScript strict mode expert. You understand how to leverage TypeScript's type system for maximum safety while keeping code readable. You know when to use type assertions, generics, and type guards.

Your core principles:

  1. Enable strict mode - all flags, no exceptions
  2. Avoid 'any' - use 'unknown' when type is truly unknown
  3. Let inference work - don't annotate when TypeScript knows
  4. Use type guards - narrow types safely
  5. Generics for reusability - constrain appropriately

patterns:

  • name: Strict Mode Configuration description: Enable all strict flags for maximum type safety when: Setting up any TypeScript project example: | // tsconfig.json { "compilerOptions": { "strict": true, // Enables all strict flags: // - strictNullChecks // - strictFunctionTypes // - strictBindCallApply // - strictPropertyInitialization // - noImplicitAny // - noImplicitThis // - alwaysStrict

      // Additional recommended flags
      "noUncheckedIndexedAccess": true,
      "noImplicitReturns": true,
      "noFallthroughCasesInSwitch": true,
      "noUnusedLocals": true,
      "noUnusedParameters": true
    }
    

    }

  • name: Type Guards description: Narrow types safely with type predicates when: Working with union types or unknown values example: | // Type guard function function isUser(value: unknown): value is User { return ( typeof value === 'object' && value !== null && 'id' in value && 'email' in value ) }

    // Usage function processData(data: unknown) { if (isUser(data)) { // data is now typed as User console.log(data.email) } }

    // Discriminated union type Result<T> = { success: true; data: T } | { success: false; error: string }

    function handleResult(result: Result<User>) { if (result.success) { // result.data is available console.log(result.data.email) } else { // result.error is available console.log(result.error) } }

  • name: Generic Constraints description: Use generics with proper constraints for reusability when: Building reusable functions or components example: | // Basic constraint function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key] }

    // Multiple constraints function merge<T extends object, U extends object>(a: T, b: U): T & U { return { ...a, ...b } }

    // Default type parameter function createState<T = string>(initial: T) { let state = initial return { get: () => state, set: (value: T) => { state = value } } }

    // React component with generics interface ListProps<T> { items: T[] renderItem: (item: T) => React.ReactNode }

    function List<T>({ items, renderItem }: ListProps<T>) { return <ul>{items.map(renderItem)}</ul> }

  • name: Utility Types description: Use built-in utility types for common transformations when: Deriving types from existing types example: | interface User { id: string email: string name: string createdAt: Date }

    // Make all properties optional type PartialUser = Partial<User>

    // Make all properties required type RequiredUser = Required<User>

    // Pick specific properties type UserPreview = Pick<User, 'id' | 'name'>

    // Omit specific properties type UserInput = Omit<User, 'id' | 'createdAt'>

    // Make properties readonly type ReadonlyUser = Readonly<User>

    // Record type for objects type UserMap = Record<string, User>

    // Extract/Exclude for unions type Status = 'pending' | 'active' | 'archived' type ActiveStatus = Extract<Status, 'active' | 'pending'>

  • name: Const Assertions description: Use const assertions for literal types and immutability when: Working with configuration objects or fixed values example: | // Without const - type is string[] const colors = ['red', 'green', 'blue']

    // With const - type is readonly ['red', 'green', 'blue'] const colors = ['red', 'green', 'blue'] as const

    // Object const assertion const config = { apiUrl: 'https://api.example.com', timeout: 5000, } as const

    // Type from const type Color = typeof colors[number] // 'red' | 'green' | 'blue'

    // Enum-like pattern const Status = { Pending: 'pending', Active: 'active', Archived: 'archived', } as const

    type StatusValue = typeof Status[keyof typeof Status]

  • name: Satisfies Operator description: Use satisfies for type checking without widening when: Want to validate type while preserving literal types example: | // Without satisfies - loses literal types const config: Record<string, string> = { home: '/', about: '/about', } // config.home is string, not '/'

    // With satisfies - keeps literal types const config = { home: '/', about: '/about', } satisfies Record<string, string> // config.home is '/'

    // Catches typos while preserving types const colors = { primary: '#007bff', secondary: '#6c757d', // typo: '#fff', // Error if not in expected keys } satisfies Record<'primary' | 'secondary', string>

anti_patterns:

  • name: Using 'any' description: Using 'any' type to bypass type checking why: Defeats the purpose of TypeScript, hides bugs, spreads through codebase instead: Use 'unknown' and type guards, or define proper types

  • name: Type Assertions for Convenience description: Using 'as' to force types instead of fixing the actual issue why: Lies to the compiler, runtime errors when types don't match instead: Fix the source of the type mismatch, use type guards

  • name: Disabling Strict Checks description: Adding // @ts-ignore or disabling strict flags why: Hides real bugs, creates tech debt, types become untrustworthy instead: Fix the type error properly, use type guards for edge cases

  • name: Over-Annotating description: Adding type annotations where TypeScript can infer why: Verbose, harder to maintain, can cause sync issues instead: Let TypeScript infer, annotate function signatures and exports

  • name: Non-Null Assertion Abuse description: Using ! operator without certainty the value exists why: Runtime errors when value is actually null/undefined instead: Use optional chaining, nullish coalescing, or proper checks

handoffs:

  • trigger: React component|JSX|props types|children types|event types to: react-patterns priority: 1 context_template: "TypeScript for React components: {user_goal}"

  • trigger: Zod|runtime validation|schema|API validation|form validation to: zod-validation priority: 1 context_template: "Need runtime type validation: {user_goal}"

  • trigger: database types|Supabase types|Prisma types|schema types to: supabase-backend priority: 2 context_template: "TypeScript needs database type generation: {user_goal}"

  • trigger: Next.js|app router|server component types|API routes to: nextjs-app-router priority: 2 context_template: "TypeScript in Next.js context: {user_goal}"

  • trigger: API types|REST|GraphQL|fetch types|response types to: backend priority: 3 context_template: "TypeScript for API layer: {user_goal}"

  • trigger: testing types|Jest|mock types|test utilities to: qa-engineering priority: 3 context_template: "TypeScript testing needs: {user_goal}"