typescript-pro
Skill0 starsChanged 3 months agoMITView on GitHub
Master advanced TypeScript features including generics, conditional types, type guards, utility types, and full-stack type safety
- Installs packages
34 other projects use a version of this.
Adopted by
Most recently taken up by
- santiago-migoni/claude-skillstheir own version, first seen Nov 8, 2026
- AxlZero21/Skillstheir own version, first seen Nov 8, 2026
- dirien/yet-another-agent-harnesstheir own version, first seen Nov 8, 2026
- lsyamsiar/claude-skillstheir own version, first seen Nov 1, 2026
- codeApe-7/ai-agent-workflowGrouptheir own version, first seen Nov 1, 2026
- liushikuan63/Qoder-Optimizationtheir own version, first seen Nov 1, 2026
Used with
Projects with it also use ui-ux-pro-max and frontend-design.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
StrayDragonSkillui-ux-pro-max
UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient.
Also in 3 projects that use this
BlockSkillfrontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Also in 3 projects that use this
Other versions34 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 34
- Jeffallan/claude-skills★ 12ksame name
- zebbern/claude-code-guide★ 4.7ksame name
- kumaran-is/claude-code-onboarding★ 35same name
- jshsakura/awesome-opencode-skills★ 30same name
- Fandry96/k3-agentic-skills★ 27same name
- sampleXbro/agentsmesh★ 27same name
- dirien/yet-another-agent-harness★ 19same name
- codeApe-7/ai-agent-workflowGroup★ 18same name
- belokonm/claude-supercode-skills★ 11same name
- PIXARTSeu/Synapse★ 9same name
24 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository27 other files it gives its agents.
- architecture-designerSkill
- architecture-patternsSkill
- code-reviewSkill
- dockerSkill
- fastapiSkill
- feature-specificationSkill
- github-issue-resolverSkill
- github-opsSkill
- kubernetes-devopsSkill
- monitoringSkill
- nextjsSkill
- nginxSkill
- prd-to-ddd-designSkill
- prd-writerSkill
- prismaSkill
- react-expertSkill
- redisSkill
- redis-storeSkill
- requirements-analysisSkill
- shadcn-uiSkill
- ssh-essentialsSkill
- task-decomposerSkill
- task-development-workflowSkill
- trpc-best-practicesSkill
- typescriptSkill
- webhookSkill
- zodSkill
The file
We split this skill into the rules it gives an agent
6 rules. 0 are common, 4 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 33 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 26
Use this skill when:
- Distinctive: line 37
Don't use: when you need:
- Distinctive: line 97
Karpathy Principle: When NOT to Use: - Don't use TypeScript for throwaway scripts (<50 lines).
- Very specific: line 140
Karpathy Principle: Goal-Driven Execution: - After writing generics, verify inference works: hover over variables, check inferred types.
- Very specific: line 518
Karpathy Principle: Composition Over Configuration: - Use utility types (Partial<T>, Pick<T>, Omit<T>) over manual interface duplication.
- Distinctive: line 522
Before deploying TypeScript code:
“Common” is measured: kept by at least 6 in 10 of the 33 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
TypeScript Pro - Advanced Type System Mastery
When to Use
Use this skill when:
- Building type-safe full-stack applications
- Creating reusable library types with complex generics
- Implementing discriminated unions for state machines
- Designing type-safe APIs with zero runtime errors
- Optimizing TypeScript compilation and type checking
- Creating branded types for domain modeling
- Setting up monorepo with project references
- Implementing advanced conditional and mapped types
Don't use when you need:
- Basic TypeScript syntax (use TypeScript basics skill)
- JavaScript without types (just use JavaScript)
- Runtime type validation (use Zod/io-ts alongside TypeScript)
- Dynamically typed code (TypeScript fights you on this)
Karpathy Principle: Think Before Coding - TypeScript types are compile-time only. They disappear at runtime. If you need runtime validation, use Zod. If you need type inference from Zod, use z.infer<typeof schema>. Don't fight the system.
Karpathy Principle: Trade-offs Everywhere - Strict mode catches bugs but slows development. Start strict in new projects. Migrate legacy gradually (skipLibCheck: true for incremental adoption). Perfect types today > working code never.
Prerequisites
Required Knowledge
- TypeScript fundamentals (types, interfaces, classes)
- JavaScript ES6+ features
- Generics basics
- Union and intersection types
- Type narrowing concepts
Required Tools
# Install TypeScript
npm install -D typescript @types/node
# Initialize tsconfig.json
npx tsc --init
# Recommended additional tools
npm install -D ts-node tsx @types/node
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-pluginStrict Mode Configuration
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"lib": ["ES2022"],
"strict": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}Karpathy Principle: Simplicity First - Enable all strict flags from the start. Retrofitting strict mode to an existing codebase is painful. Pay the type-safety cost upfront.
Karpathy Principle: When NOT to Use - Don't use TypeScript for throwaway scripts (<50 lines). Don't use it when team lacks JS fundamentals. Types add cognitive load - worth it for maintained code, not experiments.
Core Workflows
1. Advanced Generics
Generic Constraints:
// Bad: Unconstrained generic
function getProperty<T>(obj: T, key: string) {
return obj[key] // Error: no index signature
}
// Good: Constrained generic
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key] // Type-safe!
}
const user = { name: 'Alice', age: 30 }
const name = getProperty(user, 'name') // string
const age = getProperty(user, 'age') // numberGeneric Type Inference:
// Tuple with rest parameters
function tuple<T extends any[]>(...args: T): T {
return args
}
const result = tuple(1, 'hello', true) // [number, string, boolean]
// Type-safe object builder
function createObject<T extends Record<string, any>>(obj: T): T {
return obj
}
const user = createObject({
name: 'Alice',
age: 30,
}) // { name: string; age: number }Karpathy Principle: Goal-Driven Execution - After writing generics, verify inference works: hover over variables, check inferred types. If you see any or overly broad types, your constraints are wrong.
Karpathy Principle: Fail Fast, Fail Loud - Enable noUncheckedIndexedAccess. array[0] should be T | undefined, not T. This single flag prevents 80% of production runtime errors.
2. Conditional Types
Basic Conditional Types:
type IsString<T> = T extends string ? true : false
type A = IsString<string> // true
type B = IsString<number> // false
// Extract function return type
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never
type Func = () => string
type Result = ReturnType<Func> // stringDistributive Conditional Types:
type ToArray<T> = T extends any ? T[] : never
type Arr = ToArray<string | number> // string[] | number[]
// Extract non-nullable types
type NonNullable<T> = T extends null | undefined ? never : T
type Clean = NonNullable<string | null | undefined> // string3. Mapped Types
Basic Mapped Types:
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
type Partial<T> = {
[K in keyof T]?: T[K]
}
type Required<T> = {
[K in keyof T]-?: T[K] // Remove optional modifier
}
// Usage
interface User {
name: string
age?: number
}
type ReadonlyUser = Readonly<User>
// { readonly name: string; readonly age?: number }
type PartialUser = Partial<User>
// { name?: string; age?: number }Advanced Mapped Types:
// Deep readonly
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K]
}
// Pick by value type
type PickByType<T, U> = {
[K in keyof T as T[K] extends U ? K : never]: T[K]
}
interface Person {
name: string
age: number
isActive: boolean
}
type StringFields = PickByType<Person, string> // { name: string }
type NumberFields = PickByType<Person, number> // { age: number }4. Discriminated Unions
State Machine Pattern:
type LoadingState = {
status: 'loading'
}
type SuccessState<T> = {
status: 'success'
data: T
}
type ErrorState = {
status: 'error'
error: string
}
type AsyncState<T> = LoadingState | SuccessState<T> | ErrorState
function handleState(state: AsyncState<User>) {
switch (state.status) {
case 'loading':
// state is LoadingState
return 'Loading...'
case 'success':
// state is SuccessState<User>
return `Hello ${state.data.name}`
case 'error':
// state is ErrorState
return `Error: ${state.error}`
}
}Exhaustive Checks:
function assertNever(value: never): never {
throw new Error(`Unexpected value: ${value}`)
}
function handleState(state: AsyncState<User>) {
switch (state.status) {
case 'loading':
return 'Loading...'
case 'success':
return state.data.name
case 'error':
return state.error
default:
return assertNever(state) // Compile error if we miss a case
}
}5. Type Guards
User-Defined Type Guards:
interface Dog {
type: 'dog'
bark(): void
}
interface Cat {
type: 'cat'
meow(): void
}
type Animal = Dog | Cat
// Type predicate
function isDog(animal: Animal): animal is Dog {
return animal.type === 'dog'
}
function makeSound(animal: Animal) {
if (isDog(animal)) {
animal.bark() // Type narrowed to Dog
} else {
animal.meow() // Type narrowed to Cat
}
}Assertion Functions:
function assertIsDefined<T>(value: T | null | undefined): asserts value is T {
if (value === null || value === undefined) {
throw new Error('Value is null or undefined')
}
}
function processUser(user: User | null) {
assertIsDefined(user)
// user is now User (not User | null)
console.log(user.name)
}Common Patterns
1. Branded Types
type Brand<K, T> = K & { __brand: T }
type UserId = Brand<string, 'UserId'>
type OrderId = Brand<string, 'OrderId'>
function createUserId(id: string): UserId {
return id as UserId
}
function createOrderId(id: string): OrderId {
return id as OrderId
}
function getUser(userId: UserId) {
// ...
}
const userId = createUserId('123')
const orderId = createOrderId('456')
getUser(userId) // OK
getUser(orderId) // Error: OrderId not assignable to UserId2. Builder Pattern
class QueryBuilder<T> {
private conditions: Array<(item: T) => boolean> = []
where<K extends keyof T>(key: K, value: T[K]): this {
this.conditions.push(item => item[key] === value)
return this
}
execute(items: T[]): T[] {
return items.filter(item =>
this.conditions.every(condition => condition(item))
)
}
}
// Usage
interface User {
name: string
age: number
city: string
}
const users: User[] = [...]
const result = new QueryBuilder<User>()
.where('city', 'NYC')
.where('age', 30)
.execute(users)3. Type-Safe Event Emitter
type EventMap = {
'user:created': { id: string; name: string }
'user:deleted': { id: string }
'order:placed': { orderId: string; amount: number }
}
class TypedEventEmitter<T extends Record<string, any>> {
private listeners: Partial<{
[K in keyof T]: Array<(data: T[K]) => void>
}> = {}
on<K extends keyof T>(event: K, listener: (data: T[K]) => void) {
if (!this.listeners[event]) {
this.listeners[event] = []
}
this.listeners[event]!.push(listener)
}
emit<K extends keyof T>(event: K, data: T[K]) {
this.listeners[event]?.forEach(listener => listener(data))
}
}
// Usage
const emitter = new TypedEventEmitter<EventMap>()
emitter.on('user:created', (data) => {
// data is { id: string; name: string }
console.log(`User created: ${data.name}`)
})
emitter.emit('user:created', { id: '1', name: 'Alice' }) // OK
emitter.emit('user:created', { id: '1' }) // Error: missing nameCommon Pitfalls
1. Type Assertions vs Type Guards
❌ Bad (unsafe assertion):
const value: unknown = JSON.parse(input)
const user = value as User // Unsafe!✅ Good (type guard or runtime validation):
import { z } from 'zod'
const UserSchema = z.object({
name: z.string(),
age: z.number(),
})
type User = z.infer<typeof UserSchema>
const value = JSON.parse(input)
const user = UserSchema.parse(value) // Runtime validation2. Enum vs const Object
❌ Bad (enum generates runtime code):
enum Status {
Active = 'active',
Inactive = 'inactive',
}✅ Good (const object, zero runtime cost):
const Status = {
Active: 'active',
Inactive: 'inactive',
} as const
type Status = typeof Status[keyof typeof Status] // 'active' | 'inactive'3. Missing Generic Constraints
❌ Bad (unconstrained):
function merge<T>(obj1: T, obj2: T): T {
return { ...obj1, ...obj2 } // Error: spread requires object type
}✅ Good (constrained):
function merge<T extends object>(obj1: T, obj2: T): T {
return { ...obj1, ...obj2 }
}4. Type-Only Imports
❌ Bad (mixed import):
import { User } from './types' // Might include runtime code✅ Good (type-only import):
import type { User } from './types' // Guaranteed erased at runtime5. Overly Complex Types
❌ Bad (unreadable):
type ComplexType<T> = T extends (infer U)[]
? U extends object
? { [K in keyof U]: U[K] extends Function ? never : U[K] }[]
: T
: T✅ Good (split into smaller types):
type ArrayElement<T> = T extends (infer U)[] ? U : T
type OmitFunctions<T> = { [K in keyof T]: T[K] extends Function ? never : T[K] }
type SimplifiedType<T> = T extends any[] ? OmitFunctions<ArrayElement<T>>[] : TKarpathy Principle: Surgical Changes - Complex types are hard to debug. Build them incrementally. Test each layer. Use type utilities to break down complexity.
Karpathy Principle: Composition Over Configuration - Use utility types (Partial<T>, Pick<T>, Omit<T>) over manual interface duplication. DRY applies to types too.
Verification Checklist
Before deploying TypeScript code:
Type Safety
- All strict flags enabled
- No explicit
anywithout justification - Type coverage > 95% (use
type-coveragepackage) - No unsafe type assertions
- Runtime validation for external data (Zod)
Performance
- Incremental compilation enabled
- Project references used (monorepos)
skipLibCheck: truefor faster builds- No circular dependencies
Code Quality
- Type-only imports where applicable
- Discriminated unions for state
- Type guards instead of assertions
- Generic constraints where needed
Integration with Other Skills
With Next.js
- Type-safe API routes with tRPC
- Server/client component types
- Props type inference
With React
- Generic component props
- Event handler types
- Context type safety
With tRPC
- End-to-end type safety
- Router type inference
- Input/output validation
With Zod
- Runtime validation + type inference
- Schema-first API design
- Type-safe forms
References
Official Docs
Tools
- ts-node - Execute TypeScript directly
- tsx - Fast TypeScript execution
- type-coverage - Measure type coverage
Meta: Skill Quality
Completeness: ✅ Comprehensive (9/9 sections)
Karpathy Principles: ✅ 5 mentions
Code Examples: ✅ 25+ working examples
Production Tested: ✅ Used across all Alteriom TypeScript projects
Last Updated: 2026-04-13
Coverage:
- ✅ Advanced generics with constraints
- ✅ Conditional types
- ✅ Mapped types
- ✅ Discriminated unions
- ✅ Type guards and assertion functions
- ✅ Branded types
- ✅ Builder pattern
- ✅ Type-safe event emitters
- ✅ Common pitfalls and solutions
Skill Level: Advanced
Time to Learn: 6-8 hours
Prerequisites Met: TypeScript fundamentals, JavaScript ES6+
Known Gaps: None - production-ready
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

