Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
wshobson avatar

Typescript Advanced Types

  • 56.1k installs
  • 38.3k repo stars
  • Updated July 22, 2026
  • wshobson/agents

typescript-advanced-types is an agent skill that implements generics, conditional types, mapped types, template literals, and utility types for developers building fully type-safe TypeScript libraries.

About

typescript-advanced-types is comprehensive guidance for TypeScript's advanced type system: generics, conditional types, mapped types, template literal types, and built-in utility types.

  • Master generics with constraints and defaults for reusable components
  • Leverage conditional types, mapped types, and template literal types
  • Apply built-in utility types and create custom ones for inference

Typescript Advanced Types by the numbers

  • 56,127 all-time installs (skills.sh)
  • +1,700 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #25 of 16,659 AI & Agent Building skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
From the docs

What typescript-advanced-types says it does

--- name: typescript-advanced-types description: Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals
SKILL.md
npx skills add https://github.com/wshobson/agents --skill typescript-advanced-types

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs56.1k
repo stars38.3k
Security audit3 / 3 scanners passed
Last updatedJuly 22, 2026
Repositorywshobson/agents

How do you implement advanced TypeScript generic and conditional types?

Implement complex, reusable, and fully type-safe logic in TypeScript projects.

Who is it for?

TypeScript developers building libraries, frameworks, or complex domain models who need robust compile-time inference.

Skip if: Beginners learning basic interfaces and simple function signatures without advanced type-level programming.

When should I use this skill?

The user needs complex type logic, reusable generic utilities, or compile-time safety in TypeScript.

What you get

Type-safe generic utilities, mapped types, template literal types, and compile-time contracts in .ts files.

  • Generic type utilities
  • Conditional and mapped type definitions
  • Compile-time-safe API typings

Files

SKILL.mdMarkdownGitHub ↗

TypeScript Advanced Types

Comprehensive guidance for mastering TypeScript's advanced type system including generics, conditional types, mapped types, template literal types, and utility types for building robust, type-safe applications.

When to Use This Skill

  • Building type-safe libraries or frameworks
  • Creating reusable generic components
  • Implementing complex type inference logic
  • Designing type-safe API clients
  • Building form validation systems
  • Creating strongly-typed configuration objects
  • Implementing type-safe state management
  • Migrating JavaScript codebases to TypeScript

Core Concepts

1. Generics

Purpose: Create reusable, type-flexible components while maintaining type safety.

Basic Generic Function:

function identity<T>(value: T): T {
  return value;
}

const num = identity<number>(42); // Type: number
const str = identity<string>("hello"); // Type: string
const auto = identity(true); // Type inferred: boolean

Generic Constraints:

interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(item: T): T {
  console.log(item.length);
  return item;
}

logLength("hello"); // OK: string has length
logLength([1, 2, 3]); // OK: array has length
logLength({ length: 10 }); // OK: object has length
// logLength(42);             // Error: number has no length

Multiple Type Parameters:

function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const merged = merge({ name: "John" }, { age: 30 });
// Type: { name: string } & { age: number }

2. Conditional Types

Purpose: Create types that depend on conditions, enabling sophisticated type logic.

Basic Conditional Type:

type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false

Extracting Return Types:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: 1, name: "John" };
}

type User = ReturnType<typeof getUser>;
// Type: { id: number; name: string; }

Distributive Conditional Types:

type ToArray<T> = T extends any ? T[] : never;

type StrOrNumArray = ToArray<string | number>;
// Type: string[] | number[]

Nested Conditions:

type TypeName<T> = T extends string
  ? "string"
  : T extends number
    ? "number"
    : T extends boolean
      ? "boolean"
      : T extends undefined
        ? "undefined"
        : T extends Function
          ? "function"
          : "object";

type T1 = TypeName<string>; // "string"
type T2 = TypeName<() => void>; // "function"

3. Mapped Types

Purpose: Transform existing types by iterating over their properties.

Basic Mapped Type:

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

interface User {
  id: number;
  name: string;
}

type ReadonlyUser = Readonly<User>;
// Type: { readonly id: number; readonly name: string; }

Optional Properties:

type Partial<T> = {
  [P in keyof T]?: T[P];
};

type PartialUser = Partial<User>;
// Type: { id?: number; name?: string; }

Key Remapping:

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface Person {
  name: string;
  age: number;
}

type PersonGetters = Getters<Person>;
// Type: { getName: () => string; getAge: () => number; }

Filtering Properties:

type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

interface Mixed {
  id: number;
  name: string;
  age: number;
  active: boolean;
}

type OnlyNumbers = PickByType<Mixed, number>;
// Type: { id: number; age: number; }

4. Template Literal Types

Purpose: Create string-based types with pattern matching and transformation.

Basic Template Literal:

type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// Type: "onClick" | "onFocus" | "onBlur"

String Manipulation:

type UppercaseGreeting = Uppercase<"hello">; // "HELLO"
type LowercaseGreeting = Lowercase<"HELLO">; // "hello"
type CapitalizedName = Capitalize<"john">; // "John"
type UncapitalizedName = Uncapitalize<"John">; // "john"

Path Building:

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

interface Config {
  server: {
    host: string;
    port: number;
  };
  database: {
    url: string;
  };
}

type ConfigPath = Path<Config>;
// Type: "server" | "database" | "server.host" | "server.port" | "database.url"

5. Utility Types

Built-in Utility Types:

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

// Required<T> - Make all properties required
type RequiredUser = Required<PartialUser>;

// Readonly<T> - Make all properties readonly
type ReadonlyUser = Readonly<User>;

// Pick<T, K> - Select specific properties
type UserName = Pick<User, "name" | "email">;

// Omit<T, K> - Remove specific properties
type UserWithoutPassword = Omit<User, "password">;

// Exclude<T, U> - Exclude types from union
type T1 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"

// Extract<T, U> - Extract types from union
type T2 = Extract<"a" | "b" | "c", "a" | "b">; // "a" | "b"

// NonNullable<T> - Exclude null and undefined
type T3 = NonNullable<string | null | undefined>; // string

// Record<K, T> - Create object type with keys K and values T
type PageInfo = Record<"home" | "about", { title: string }>;

Detailed worked examples and patterns

Detailed sections (starting with ## Advanced Patterns) live in references/details.md. Read that file when the navigation summary above is insufficient.

Best Practices

1. Use `unknown` over `any`: Enforce type checking 2. Prefer `interface` for object shapes: Better error messages 3. Use `type` for unions and complex types: More flexible 4. Leverage type inference: Let TypeScript infer when possible 5. Create helper types: Build reusable type utilities 6. Use const assertions: Preserve literal types 7. Avoid type assertions: Use type guards instead 8. Document complex types: Add JSDoc comments 9. Use strict mode: Enable all strict compiler options 10. Test your types: Use type tests to verify type behavior

Type Testing

// Type assertion tests
type AssertEqual<T, U> = [T] extends [U]
  ? [U] extends [T]
    ? true
    : false
  : false;

type Test1 = AssertEqual<string, string>; // true
type Test2 = AssertEqual<string, number>; // false
type Test3 = AssertEqual<string | number, string>; // false

// Expect error helper
type ExpectError<T extends never> = T;

// Example usage
type ShouldError = ExpectError<AssertEqual<string, number>>;

Common Pitfalls

1. Over-using `any`: Defeats the purpose of TypeScript 2. Ignoring strict null checks: Can lead to runtime errors 3. Too complex types: Can slow down compilation 4. Not using discriminated unions: Misses type narrowing opportunities 5. Forgetting readonly modifiers: Allows unintended mutations 6. Circular type references: Can cause compiler errors 7. Not handling edge cases: Like empty arrays or null values

Performance Considerations

  • Avoid deeply nested conditional types
  • Use simple types when possible
  • Cache complex type computations
  • Limit recursion depth in recursive types
  • Use build tools to skip type checking in production

Related skills

How it compares

Choose typescript-advanced-types over basic TypeScript skills when problems require type-level programming, not simple interface declarations.

FAQ

What TypeScript features does typescript-advanced-types cover?

typescript-advanced-types covers generics, conditional types, mapped types, template literal types, and utility types for building reusable, compile-time-safe logic.

When should developers use typescript-advanced-types?

Use typescript-advanced-types when implementing complex type logic, creating generic libraries or frameworks, or ensuring compile-time safety for API shapes.

Is Typescript Advanced Types safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

AI & Agent Buildingbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.