
Typescript Pro
Ship type-safe TypeScript with advanced generics, conditional types, and mapped types instead of copying patterns from Stack Overflow.
Overview
TypeScript Pro is an agent skill most often used in Build (also Ship review, backend integrations) that teaches and applies advanced TypeScript typing patterns—generics, conditionals, and mapped types—for safer solo-buil
Install
npx skills add https://github.com/jeffallan/claude-skills --skill typescript-proWhat is this skill?
- Generic constraints with keyof, multiple extends, and infer-based unwrappers
- Conditional and distributive conditional types with flattening recipes
- Mapped types for Readonly, Partial, and API response discriminated unions
- Runnable snippet patterns for getProperty, merge, and NonNullable-style utilities
Adoption & trust: 3.6k installs on skills.sh; 9.7k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are shipping TypeScript features but keep reaching for weak types, duplicated utility aliases, or unclear generic bounds.
Who is it for?
Solo builders maintaining strict TS apps who want advanced type recipes on demand during feature work.
Skip if: Teams that only need beginner TS setup or projects still on plain JavaScript with no migration plan.
When should I use this skill?
User is implementing or refactoring TypeScript and needs advanced generic, conditional, or mapped-type patterns.
What do I get? / Deliverables
Your agent drafts constrained generics, conditional helpers, and mapped-type refactors inline so interfaces stay precise without a separate design doc.
- In-editor type definitions and refactors using documented patterns
- Reusable utility type snippets aligned to your domain models
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Canonical shelf is Build because the skill is procedural reference for authoring and refactoring TS types during implementation. Frontend is the default shelf for TypeScript ergonomics in agent-assisted UI and full-stack repos, though the same patterns apply in Node backends.
Where it fits
Tighten React component props with mapped Readonly and discriminated union API responses.
Add generic repository helpers with keyof constraints for a Node API.
Replace lingering any types with conditional UnwrapPromise-style utilities before merge.
How it compares
Reference skill package for type-level patterns, not an ESLint rule pack or a runtime validation framework.
Common Questions / FAQ
Who is typescript-pro for?
Indie and solo developers who already write TypeScript and want agent help with advanced typing—not first-time TS learners.
When should I use typescript-pro?
Use it during Build when modeling APIs or UI state, during Ship review when hardening types before release, and when refactoring shared utils in backend integrations.
Is typescript-pro safe to install?
Review the Security Audits panel on this Prism page and inspect the skill bundle in your repo before granting broad filesystem access to your agent.
SKILL.md
READMESKILL.md - Typescript Pro
# Advanced Types ## Generic Constraints ```typescript // Basic constraint function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } // Multiple constraints interface HasId { id: number; } interface HasName { name: string; } function merge<T extends HasId, U extends HasName>(obj1: T, obj2: U): T & U { return { ...obj1, ...obj2 }; } // Generic constraint with default type ApiResponse<T = unknown, E = Error> = | { success: true; data: T } | { success: false; error: E }; // Constraint with infer type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; type Result = UnwrapPromise<Promise<string>>; // string ``` ## Conditional Types ```typescript // Basic conditional type type IsString<T> = T extends string ? true : false; // Distributive conditional types type ToArray<T> = T extends any ? T[] : never; type StringOrNumberArray = ToArray<string | number>; // string[] | number[] // Non-distributive (use tuple) type ToArrayNonDist<T> = [T] extends [any] ? T[] : never; type BothArray = ToArrayNonDist<string | number>; // (string | number)[] // Nested conditionals for type extraction type Flatten<T> = T extends Array<infer U> ? U extends Array<infer V> ? Flatten<V> : U : T; type Nested = Flatten<string[][][]>; // string // Exclude null/undefined type NonNullable<T> = T extends null | undefined ? never : T; ``` ## Mapped Types ```typescript // Basic mapped type type ReadOnly<T> = { readonly [K in keyof T]: T[K]; }; // Optional properties type Partial<T> = { [K in keyof T]?: T[K]; }; // Required properties type Required<T> = { [K in keyof T]-?: T[K]; // Remove optional modifier }; // Key remapping with 'as' type Getters<T> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]; }; interface Person { name: string; age: number; } type PersonGetters = Getters<Person>; // { getName: () => string; getAge: () => number; } // Filtering keys type PickByType<T, U> = { [K in keyof T as T[K] extends U ? K : never]: T[K]; }; type StringFields = PickByType<Person, string>; // { name: string } ``` ## Template Literal Types ```typescript // Basic template literal type EmailLocale = 'en' | 'es' | 'fr'; type EmailType = 'welcome' | 'reset-password'; type EmailTemplate = `${EmailLocale}_${EmailType}`; // 'en_welcome' | 'en_reset-password' | 'es_welcome' | ... // Intrinsic string manipulation type Uppercase<S extends string> = intrinsic; type Lowercase<S extends string> = intrinsic; type Capitalize<S extends string> = intrinsic; type Uncapitalize<S extends string> = intrinsic; type EventName<T extends string> = `on${Capitalize<T>}`; type ClickEvent = EventName<'click'>; // 'onClick' // Template literal with mapped types type CSSProperties = { [K in 'color' | 'background' | 'border' as `--${K}`]: string; }; // { '--color': string; '--background': string; '--border': string } // Pattern matching with infer type ExtractRouteParams<T extends string> = T extends `${infer _Start}/:${infer Param}/${infer Rest}` ? Param | ExtractRouteParams<`/${Rest}`> : T extends `${infer _Start}/:${infer Param}` ? Param : never; type Params = ExtractRouteParams<'/users/:id/posts/:postId'>; // 'id' | 'postId' ``` ## Higher-Kinded Types (Simulation) ```typescript // Type-level function simulation interface TypeClass<F> { map: <A, B>(f: (a: A) => B, fa: any) => any; } // Functor pattern type Maybe<T> = { type: 'just'; value: T } | { type: 'nothing' }; const MaybeFunctor: TypeClass<Maybe<any>> = { map: <A, B>(f: (a: A) => B, ma: Maybe<A>): Maybe<B> => { return ma.type === 'just' ? { type: 'just', value: f(ma.value) } : { type: 'nothing' }; } }; // Builder pattern with generics type Builder<T, K extends keyof T = never> = { with<P extends Exclude<keyof T, K>>( key: P, value: T[P] ): Builder<T, K | P>; build(): K extends keyof T ? T : never; }; ``` ## Recursive Types ```typescript // JSON type type JSONValue = | string