All skills
jeffallan avatar

/typescript-pro

@efebc44
by jeffallanjeffallan/claude-skills12k stars
1,124

Implements advanced TypeScript type systems, creates custom type guards, utility types, and branded types, and configures tRPC for end-to-end type safety. Use when building TypeScript applications requiring advanced generics, conditional or mapped types, discriminated unions, monorepo setup, or full-stack type safety with tRPC.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/typescript-pro

This session only. Nothing lands on disk.

referencesadvanced-types.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Advanced Types

Generic Constraints

// 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

// 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

// 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

// 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)

// 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

// JSON type
type JSONValue =
  | string
  | number
  | boolean
  | null
  | JSONValue[]
  | { [key: string]: JSONValue };

// Deep partial
type DeepPartial<T> = T extends object ? {
  [K in keyof T]?: DeepPartial<T[K]>;
} : T;

// Deep readonly
type DeepReadonly<T> = T extends object ? {
  readonly [K in keyof T]: DeepReadonly<T[K]>;
} : T;

// Path type for nested objects
type PathsToProps<T> = T extends object ? {
  [K in keyof T]: K extends string
    ? T[K] extends object
      ? K | `${K}.${PathsToProps<T[K]>}`
      : K
    : never;
}[keyof T] : never;

interface User {
  profile: {
    name: string;
    settings: {
      theme: string;
    };
  };
}

type UserPaths = PathsToProps<User>;
// 'profile' | 'profile.name' | 'profile.settings' | 'profile.settings.theme'

Variance and Contravariance

// Covariance (return types)
type Producer<T> = () => T;
let stringProducer: Producer<string> = () => 'hello';
let objectProducer: Producer<object> = stringProducer; // OK: string is object

// Contravariance (parameter types)
type Consumer<T> = (value: T) => void;
let objectConsumer: Consumer<object> = (obj) => console.log(obj);
let stringConsumer: Consumer<string> = objectConsumer; // OK in strict mode

// Invariance (mutable properties)
interface Box<T> {
  value: T;
  setValue(v: T): void;
}

let stringBox: Box<string> = { value: '', setValue: (v) => {} };
// let objectBox: Box<object> = stringBox; // Error: invariant

Type-Level Programming

// Type-level addition (limited)
type Length<T extends any[]> = T['length'];
type Concat<A extends any[], B extends any[]> = [...A, ...B];

// Type-level conditionals
type If<Condition extends boolean, Then, Else> =
  Condition extends true ? Then : Else;

// Type-level equality
type Equal<X, Y> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? true : false;

// Assert equal types (for testing)
type Assert<T extends true> = T;
type Test = Assert<Equal<1 | 2, 2 | 1>>; // OK

Quick Reference

Pattern Use Case
T extends U ? X : Y Conditional type logic
infer R Extract types from patterns
K in keyof T Iterate over object keys
as NewKey Remap keys in mapped types
Template literals String pattern types
T extends any Distributive conditionals
[T] extends [any] Non-distributive check
-? modifier Remove optional
readonly modifier Make immutable

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub17d

    The skill provides advanced TypeScript development guidance and templates. Automated scanners flagged the documentation URL and the main file, but manual review suggests these are false positives as the content is purely technical documentation and standard configuration examples. The skill instructs the agent to run standard development tools like tsc, which is expected behavior for its purpose.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    6 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at efebc44. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 5 months ago
Other metadata
metadata
{
  "author": "https://github.com/Jeffallan",
  "version": "1.1.0",
  "domain": "language",
  "triggers": "TypeScript, generics, type safety, conditional types, mapped types, tRPC, tsconfig, type guards, discriminated unions",
  "role": "specialist",
  "scope": "implementation",
  "output-format": "code",
  "related-skills": "fullstack-guardian, api-designer"
}

README badge

README badge for jeffallan/claude-skills/typescript-pro